* [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
@ 2022-07-18 8:43 liuzhensong
2022-07-18 8:43 ` [PATCH 2/5 v1] LoongArch:opcodes: " liuzhensong
` (5 more replies)
0 siblings, 6 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-18 8:43 UTC (permalink / raw)
To: binutils; +Cc: xuchenghua, mengqinggang, liuzhensong
This is the v1 version of patches to support new relocs for LoongArch.
The new reloc types docnments are on:
https://github.com/loongson/LoongArch-Documentation/pull/57/files
The testsuite status:
=== binutils Summary ===
# of expected passes 241
# of unsupported tests 6
=== gas Summary ===
# of expected passes 270
# of unsupported tests 7
=== ld Summary ===
# of expected passes 1457
# of expected failures 11
# of untested testcases 1
# of unsupported tests 154
Add new reloc types support, the new relocate type
definition depends which operation needs of linker.
---
bfd/bfd-in2.h | 36 ++
bfd/elfnn-loongarch.c | 1194 ++++++++++++++++++++++------------
bfd/elfxx-loongarch.c | 1354 +++++++++++++++++++++++++++++----------
bfd/elfxx-loongarch.h | 4 +
bfd/libbfd.h | 36 ++
bfd/reloc.c | 79 +++
include/elf/loongarch.h | 142 +++-
7 files changed, 2095 insertions(+), 750 deletions(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 4e1182e93d4..a71b3e82057 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6274,6 +6274,42 @@ assembler and not (currently) written to any object files. */
BFD_RELOC_LARCH_SUB24,
BFD_RELOC_LARCH_SUB32,
BFD_RELOC_LARCH_SUB64,
+ BFD_RELOC_LARCH_B16,
+ BFD_RELOC_LARCH_B21,
+ BFD_RELOC_LARCH_B26,
+ BFD_RELOC_LARCH_ABS_HI20,
+ BFD_RELOC_LARCH_ABS_LO12,
+ BFD_RELOC_LARCH_ABS64_LO20,
+ BFD_RELOC_LARCH_ABS64_HI12,
+ BFD_RELOC_LARCH_PCALA_HI20,
+ BFD_RELOC_LARCH_PCALA_LO12,
+ BFD_RELOC_LARCH_PCALA64_LO20,
+ BFD_RELOC_LARCH_PCALA64_HI12,
+ BFD_RELOC_LARCH_GOT_PC_HI20,
+ BFD_RELOC_LARCH_GOT_PC_LO12,
+ BFD_RELOC_LARCH_GOT64_PC_LO20,
+ BFD_RELOC_LARCH_GOT64_PC_HI12,
+ BFD_RELOC_LARCH_GOT64_HI20,
+ BFD_RELOC_LARCH_GOT64_LO12,
+ BFD_RELOC_LARCH_GOT64_LO20,
+ BFD_RELOC_LARCH_GOT64_HI12,
+ BFD_RELOC_LARCH_TLS_LE_HI20,
+ BFD_RELOC_LARCH_TLS_LE_LO12,
+ BFD_RELOC_LARCH_TLS_LE64_LO20,
+ BFD_RELOC_LARCH_TLS_LE64_HI12,
+ BFD_RELOC_LARCH_TLS_IE_PC_HI20,
+ BFD_RELOC_LARCH_TLS_IE_PC_LO12,
+ BFD_RELOC_LARCH_TLS_IE64_PC_LO20,
+ BFD_RELOC_LARCH_TLS_IE64_PC_HI12,
+ BFD_RELOC_LARCH_TLS_IE64_HI20,
+ BFD_RELOC_LARCH_TLS_IE64_LO12,
+ BFD_RELOC_LARCH_TLS_IE64_LO20,
+ BFD_RELOC_LARCH_TLS_IE64_HI12,
+ BFD_RELOC_LARCH_TLS_LD_PC_HI20,
+ BFD_RELOC_LARCH_TLS_LD64_HI20,
+ BFD_RELOC_LARCH_TLS_GD_PC_HI20,
+ BFD_RELOC_LARCH_TLS_GD64_HI20,
+ BFD_RELOC_LARCH_RELAX,
BFD_RELOC_UNUSED };
typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 5b44901b9e0..4eeaeb44eff 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -122,14 +122,16 @@ struct loongarch_elf_link_hash_table
#define elf_backend_plt_readonly 1
-#define elf_backend_want_plt_sym 0
+#define elf_backend_want_plt_sym 1
#define elf_backend_plt_alignment 4
#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
#define elf_backend_want_got_sym 1
#define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
#define elf_backend_want_dynrelro 1
+#define elf_backend_rela_normal 1
/* Generate a PLT header. */
@@ -607,9 +609,6 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
struct elf_link_hash_entry *h;
Elf_Internal_Sym *isym = NULL;
- int need_dynreloc;
- int only_need_pcrel;
-
r_symndx = ELFNN_R_SYM (rel->r_info);
r_type = ELFNN_R_TYPE (rel->r_info);
@@ -622,7 +621,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
if (r_symndx < symtab_hdr->sh_info)
{
/* A local symbol. */
- isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx);
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
if (isym == NULL)
return false;
@@ -655,17 +654,20 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
+ /* Create 'irelifunc' in PIC object. */
+ if (bfd_link_pic (info)
+ && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
+ return false;
+ /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
+ else if (!htab->elf.splt
+ && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
+ return false;
/* Create the ifunc sections, iplt and ipltgot, for static
executables. */
if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
&& !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
return false;
- if (!htab->elf.splt
- && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
- /* If '.plt' not represent, create '.iplt' to deal with ifunc. */
- return false;
-
if (h->plt.refcount < 0)
h->plt.refcount = 0;
h->plt.refcount++;
@@ -674,17 +676,27 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
}
- need_dynreloc = 0;
- only_need_pcrel = 0;
+ int need_dynreloc = 0;
+ int only_need_pcrel = 0;
+
switch (r_type)
{
+ case R_LARCH_GOT_PC_HI20:
+ case R_LARCH_GOT64_HI20:
case R_LARCH_SOP_PUSH_GPREL:
+ /* For la.global. */
+ if (h)
+ h->pointer_equality_needed = 1;
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
r_symndx,
GOT_NORMAL))
return false;
break;
+ case R_LARCH_TLS_LD_PC_HI20:
+ case R_LARCH_TLS_LD64_HI20:
+ case R_LARCH_TLS_GD_PC_HI20:
+ case R_LARCH_TLS_GD64_HI20:
case R_LARCH_SOP_PUSH_TLS_GD:
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
r_symndx,
@@ -692,6 +704,8 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
return false;
break;
+ case R_LARCH_TLS_IE_PC_HI20:
+ case R_LARCH_TLS_IE64_HI20:
case R_LARCH_SOP_PUSH_TLS_GOT:
if (bfd_link_pic (info))
/* May fail for lazy-bind. */
@@ -703,6 +717,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
return false;
break;
+ case R_LARCH_TLS_LE_HI20:
case R_LARCH_SOP_PUSH_TLS_TPREL:
if (!bfd_link_executable (info))
return false;
@@ -715,6 +730,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
return false;
break;
+ case R_LARCH_ABS_HI20:
case R_LARCH_SOP_PUSH_ABSOLUTE:
if (h != NULL)
/* If this reloc is in a read-only section, we might
@@ -726,16 +742,45 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
h->non_got_ref = 1;
break;
- case R_LARCH_SOP_PUSH_PCREL:
+ case R_LARCH_PCALA_HI20:
if (h != NULL)
{
h->non_got_ref = 1;
+ h->pointer_equality_needed = 1;
+ }
+
+ break;
+
+ case R_LARCH_B21:
+ case R_LARCH_B16:
+ case R_LARCH_B26:
+ if (h != NULL)
+ {
+ h->needs_plt = 1;
+ if (!bfd_link_pic (info))
+ h->non_got_ref = 1;
+
+ /* We try to create PLT stub for all non-local function. */
+ if (h->plt.refcount < 0)
+ h->plt.refcount = 0;
+ h->plt.refcount++;
+ }
+
+ break;
+
+ case R_LARCH_SOP_PUSH_PCREL:
+ if (h != NULL)
+ {
+ if (!bfd_link_pic (info))
+ h->non_got_ref = 1;
/* We try to create PLT stub for all non-local function. */
if (h->plt.refcount < 0)
h->plt.refcount = 0;
h->plt.refcount++;
+ h->pointer_equality_needed = 1;
}
+
break;
case R_LARCH_SOP_PUSH_PLT_PCREL:
@@ -762,6 +807,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_LARCH_JUMP_SLOT:
case R_LARCH_32:
case R_LARCH_64:
+
need_dynreloc = 1;
/* If resolved symbol is defined in this object,
@@ -774,9 +820,6 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
Thus, only under pde, it needs pcrel only. We discard it. */
only_need_pcrel = bfd_link_pde (info);
- if (h != NULL)
- h->non_got_ref = 1;
-
if (h != NULL
&& (!bfd_link_pic (info)
|| h->type == STT_GNU_IFUNC))
@@ -899,9 +942,7 @@ loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h)
{
struct loongarch_elf_link_hash_table *htab;
- struct loongarch_elf_link_hash_entry *eh;
bfd *dynobj;
- asection *s, *srel;
htab = loongarch_elf_hash_table (info);
BFD_ASSERT (htab != NULL);
@@ -951,73 +992,9 @@ loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
return true;
}
- /* This is a reference to a symbol defined by a dynamic object which
- is not a function. */
-
- /* If we are creating a shared library, we must presume that the
- only references to the symbol are via the global offset table.
- For such cases we need not do anything here; the relocations will
- be handled correctly by relocate_section. */
- if (bfd_link_dll (info))
- return true;
-
- /* If there are no references to this symbol that do not use the
- GOT, we don't need to generate a copy reloc. */
- if (!h->non_got_ref)
- return true;
-
- /* If -z nocopyreloc was given, we won't generate them either. */
- if (info->nocopyreloc)
- {
- h->non_got_ref = 0;
- return true;
- }
-
- /* If we don't find any dynamic relocs in read-only sections, then
- we'll be keeping the dynamic relocs and avoiding the copy reloc. */
- if (!readonly_dynrelocs (h))
- {
- h->non_got_ref = 0;
- return true;
- }
-
- /* We must allocate the symbol in our .dynbss section, which will
- become part of the .bss section of the executable. There will be
- an entry for this symbol in the .dynsym section. The dynamic
- object will contain position independent code, so all references
- from the dynamic object to this symbol will go through the global
- offset table. The dynamic linker will use the .dynsym entry to
- determine the address it must put in the global offset table, so
- both the dynamic object and the regular object will refer to the
- same memory location for the variable. */
-
- /* We must generate a R_LARCH_COPY reloc to tell the dynamic linker
- to copy the initial value out of the dynamic object and into the
- runtime process image. We need to remember the offset into the
- .rel.bss section we are going to use. */
- eh = (struct loongarch_elf_link_hash_entry *) h;
- if (eh->tls_type & ~GOT_NORMAL)
- {
- s = htab->sdyntdata;
- srel = htab->elf.srelbss;
- }
- else if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
- {
- s = htab->elf.sdynrelro;
- srel = htab->elf.sreldynrelro;
- }
- else
- {
- s = htab->elf.sdynbss;
- srel = htab->elf.srelbss;
- }
- if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
- {
- srel->size += sizeof (ElfNN_External_Rela);
- h->needs_copy = 1;
- }
-
- return _bfd_elf_adjust_dynamic_copy (info, h, s);
+ /* R_LARCH_COPY is not adept glibc, not to generate. */
+ /* Can not print anything, because make check ld. */
+ return true;
}
/* Allocate space in .plt, .got and associated reloc sections for
@@ -1039,6 +1016,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
info = (struct bfd_link_info *) inf;
htab = loongarch_elf_hash_table (info);
+ bool dyn = htab->elf.dynamic_sections_created;
BFD_ASSERT (htab != NULL);
do
@@ -1052,9 +1030,12 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (htab->elf.splt)
{
- if (h->dynindx == -1 && !h->forced_local
- && !bfd_elf_link_record_dynamic_symbol (info, h))
- return false;
+ if (h->dynindx == -1 && !h->forced_local && dyn
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
+ }
if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
&& h->type != STT_GNU_IFUNC)
@@ -1090,7 +1071,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
location in the .plt. This is required to make function
pointers compare as equal between the normal executable and
the shared library. */
- if (!bfd_link_pic(info)
+ if (!bfd_link_pic (info)
&& !h->def_regular)
{
h->root.u.def.section = plt;
@@ -1107,51 +1088,68 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (0 < h->got.refcount)
{
asection *s;
- bool dyn;
int tls_type = loongarch_elf_hash_entry (h)->tls_type;
/* Make sure this symbol is output as a dynamic symbol.
Undefined weak syms won't yet be marked as dynamic. */
- if (h->dynindx == -1 && !h->forced_local)
+ if (h->dynindx == -1 && !h->forced_local && dyn
+ && h->root.type == bfd_link_hash_undefweak)
{
- if (SYMBOL_REFERENCES_LOCAL (info, h)
- && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
- && h->start_stop)
- {
- /* The pr21964-4. do nothing. */
- }
- else
- {
- if( !bfd_elf_link_record_dynamic_symbol (info, h))
- return false;
- }
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
}
s = htab->elf.sgot;
h->got.offset = s->size;
- dyn = htab->elf.dynamic_sections_created;
if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
{
/* TLS_GD needs two dynamic relocs and two GOT slots. */
if (tls_type & GOT_TLS_GD)
{
s->size += 2 * GOT_ENTRY_SIZE;
- htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
+ if (bfd_link_executable (info))
+ {
+ /* Link exe and not defined local. */
+ if (!SYMBOL_REFERENCES_LOCAL (info, h))
+ htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
+ }
+ else
+ {
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+ else
+ htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
+ }
}
/* TLS_IE needs one dynamic reloc and one GOT slot. */
if (tls_type & GOT_TLS_IE)
{
s->size += GOT_ENTRY_SIZE;
- htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+
+ if (bfd_link_executable (info))
+ {
+ /* Link exe and not defined local. */
+ if (!SYMBOL_REFERENCES_LOCAL (info, h))
+ htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+ }
+ else
+ {
+ htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+ }
}
}
else
{
s->size += GOT_ENTRY_SIZE;
- if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
- && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
- || h->type == STT_GNU_IFUNC)
+ if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (bfd_link_pic (info)
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
+ h))
+ && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
+ /* Undefined weak symbol in static PIE resolves to 0 without
+ any dynamic relocations. */
htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
}
}
@@ -1161,7 +1159,13 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (h->dyn_relocs == NULL)
return true;
- if (SYMBOL_REFERENCES_LOCAL (info, h))
+ /* Extra dynamic relocate,
+ * R_LARCH_64
+ * R_LARCH_TLS_DTPRELNN
+ * R_LARCH_JUMP_SLOT
+ * R_LARCH_NN. */
+
+ if (SYMBOL_CALLS_LOCAL (info, h))
{
struct elf_dyn_relocs **pp;
@@ -1178,13 +1182,20 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (h->root.type == bfd_link_hash_undefweak)
{
- if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
+ if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || (!bfd_link_pic (info) && h->non_got_ref))
h->dyn_relocs = NULL;
- else if (h->dynindx == -1 && !h->forced_local
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
- && !bfd_elf_link_record_dynamic_symbol (info, h))
- return false;
+ else if (h->dynindx == -1 && !h->forced_local)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
+
+ if (h->dynindx == -1)
+ h->dyn_relocs = NULL;
+ }
}
for (p = h->dyn_relocs; p != NULL; p = p->next)
@@ -1200,8 +1211,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
ifunc dynamic relocs. */
static bool
-elfNN_loongarch_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
- void *inf)
+elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
struct bfd_link_info *info;
/* An example of a bfd_link_hash_indirect symbol is versioned
@@ -1223,14 +1233,14 @@ elfNN_loongarch_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
here if it is defined and referenced in a non-shared object. */
- if (h->type == STT_GNU_IFUNC
- && h->def_regular)
+ if (h->type == STT_GNU_IFUNC && h->def_regular)
return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
&h->dyn_relocs,
PLT_ENTRY_SIZE,
PLT_HEADER_SIZE,
GOT_ENTRY_SIZE,
false);
+
return true;
}
@@ -1238,7 +1248,7 @@ elfNN_loongarch_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
ifunc dynamic relocs. */
static bool
-elfNN_loongarch_allocate_local_dynrelocs (void **slot, void *inf)
+elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
{
struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
@@ -1249,7 +1259,7 @@ elfNN_loongarch_allocate_local_dynrelocs (void **slot, void *inf)
|| h->root.type != bfd_link_hash_defined)
abort ();
- return elfNN_loongarch_allocate_ifunc_dynrelocs (h, inf);
+ return elfNN_allocate_ifunc_dynrelocs (h, inf);
}
/* Set DF_TEXTREL if we find any dynamic relocs that apply to
@@ -1367,16 +1377,21 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd,
if (0 < *local_got)
{
*local_got = s->size;
- s->size += GOT_ENTRY_SIZE;
+ /* TLS gd use two got. */
if (*local_tls_type & GOT_TLS_GD)
+ s->size += GOT_ENTRY_SIZE * 2;
+ else
+ /* Normal got, tls ie/ld use one got. */
s->size += GOT_ENTRY_SIZE;
- /* If R_LARCH_RELATIVE. */
- if (bfd_link_pic (info)
- /* Or R_LARCH_TLS_DTPRELNN or R_LARCH_TLS_TPRELNN. */
- || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
- srel->size += sizeof (ElfNN_External_Rela);
+ if (bfd_link_executable (info)
+ && (*local_tls_type & (GOT_TLS_GD| GOT_TLS_IE)))
+ ;/* Do nothing. */
+ else
+ {
+ srel->size += sizeof (ElfNN_External_Rela);
+ }
}
else
*local_got = MINUS_ONE;
@@ -1389,11 +1404,11 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd,
/* Allocate global ifunc sym .plt and .got entries, and space for global
ifunc sym dynamic relocs. */
- elf_link_hash_traverse (&htab->elf, elfNN_loongarch_allocate_ifunc_dynrelocs, info);
+ elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info);
/* Allocate .plt and .got entries, and space for local ifunc symbols. */
htab_traverse (htab->loc_hash_table,
- (void *) elfNN_loongarch_allocate_local_dynrelocs, info);
+ (void *) elfNN_allocate_local_ifunc_dynrelocs, info);
/* Don't allocate .got.plt section if there are no PLT. */
if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
@@ -1542,10 +1557,13 @@ loongarch_top (int64_t *val)
static void
loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
{
+ BFD_ASSERT (s && s->contents);
const struct elf_backend_data *bed;
bfd_byte *loc;
bed = get_elf_backend_data (abfd);
+ if (!(s->size > s->reloc_count * bed->s->sizeof_rela))
+ BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela);
loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
bed->s->swap_reloca_out (abfd, rel, loc);
}
@@ -1594,19 +1612,15 @@ loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
return bfd_reloc_ok;
}
-/* Emplace a static relocation. */
-
static bfd_reloc_status_type
perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
reloc_howto_type *howto, bfd_vma value,
bfd *input_bfd, bfd_byte *contents)
{
- uint32_t insn1;
int64_t opr1, opr2, opr3;
bfd_reloc_status_type r = bfd_reloc_ok;
int bits = bfd_get_reloc_size (howto) * 8;
-
switch (ELFNN_R_TYPE (rel->r_info))
{
case R_LARCH_SOP_PUSH_PCREL:
@@ -1679,6 +1693,8 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
case R_LARCH_SOP_POP_32_S_10_12:
case R_LARCH_SOP_POP_32_S_10_16:
case R_LARCH_SOP_POP_32_S_10_16_S2:
+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
case R_LARCH_SOP_POP_32_S_5_20:
case R_LARCH_SOP_POP_32_U_10_12:
case R_LARCH_SOP_POP_32_U:
@@ -1694,67 +1710,6 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
contents, (bfd_vma)opr1);
break;
- case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
- {
- r = loongarch_pop (&opr1);
- if (r != bfd_reloc_ok)
- break;
-
- if ((opr1 & 0x3) != 0)
- {
- r = bfd_reloc_overflow;
- break;
- }
-
- uint32_t imm = opr1 >> howto->rightshift;
- if ((imm & (~0xfffffU)) && ((imm & (~0xfffffU)) != (~0xfffffU)))
- {
- r = bfd_reloc_overflow;
- break;
- }
- r = loongarch_check_offset (rel, input_section);
- if (r != bfd_reloc_ok)
- break;
-
- insn1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
- insn1 = (insn1 & howto->src_mask)
- | ((imm & 0xffffU) << 10)
- | ((imm & 0x1f0000U) >> 16);
- bfd_put (bits, input_bfd, insn1, contents + rel->r_offset);
- break;
- }
-
- case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
- {
- r = loongarch_pop (&opr1);
- if (r != bfd_reloc_ok)
- break;
-
- if ((opr1 & 0x3) != 0)
- {
- r = bfd_reloc_overflow;
- break;
- }
-
- uint32_t imm = opr1 >> howto->rightshift;
- if ((imm & (~0x1ffffffU)) && (imm & (~0x1ffffffU)) != (~0x1ffffffU))
- {
- r = bfd_reloc_overflow;
- break;
- }
-
- r = loongarch_check_offset (rel, input_section);
- if (r != bfd_reloc_ok)
- break;
-
- insn1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
- insn1 = ((insn1 & howto->src_mask)
- | ((imm & 0xffffU) << 10)
- | ((imm & 0x3ff0000U) >> 16));
- bfd_put (bits, input_bfd, insn1, contents + rel->r_offset);
- break;
- }
-
case R_LARCH_TLS_DTPREL32:
case R_LARCH_32:
case R_LARCH_TLS_DTPREL64:
@@ -1792,6 +1747,55 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
bfd_put (bits, input_bfd, opr1 - value, contents + rel->r_offset);
break;
+ /* New reloc type.
+ R_LARCH_B16 ~ R_LARCH_TLS_GD64_HI20. */
+ case R_LARCH_B16:
+ case R_LARCH_B21:
+ case R_LARCH_B26:
+ case R_LARCH_ABS_HI20:
+ case R_LARCH_ABS_LO12:
+ case R_LARCH_ABS64_LO20:
+ case R_LARCH_ABS64_HI12:
+ case R_LARCH_PCALA_HI20:
+ case R_LARCH_PCALA_LO12:
+ case R_LARCH_PCALA64_LO20:
+ case R_LARCH_PCALA64_HI12:
+ case R_LARCH_GOT_PC_HI20:
+ case R_LARCH_GOT_PC_LO12:
+ case R_LARCH_GOT64_PC_LO20:
+ case R_LARCH_GOT64_PC_HI12:
+ case R_LARCH_GOT64_HI20:
+ case R_LARCH_GOT64_LO12:
+ case R_LARCH_GOT64_LO20:
+ case R_LARCH_GOT64_HI12:
+ case R_LARCH_TLS_LE_HI20:
+ case R_LARCH_TLS_LE_LO12:
+ case R_LARCH_TLS_LE64_LO20:
+ case R_LARCH_TLS_LE64_HI12:
+ case R_LARCH_TLS_IE_PC_HI20:
+ case R_LARCH_TLS_IE_PC_LO12:
+ case R_LARCH_TLS_IE64_PC_LO20:
+ case R_LARCH_TLS_IE64_PC_HI12:
+ case R_LARCH_TLS_IE64_HI20:
+ case R_LARCH_TLS_IE64_LO12:
+ case R_LARCH_TLS_IE64_LO20:
+ case R_LARCH_TLS_IE64_HI12:
+ case R_LARCH_TLS_LD_PC_HI20:
+ case R_LARCH_TLS_LD64_HI20:
+ case R_LARCH_TLS_GD_PC_HI20:
+ case R_LARCH_TLS_GD64_HI20:
+ r = loongarch_check_offset (rel, input_section);
+ if (r != bfd_reloc_ok)
+ break;
+
+ r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
+ howto, input_bfd,
+ contents, value);
+ break;
+
+ case R_LARCH_RELAX:
+ break;
+
default:
r = bfd_reloc_notsupported;
}
@@ -1900,7 +1904,6 @@ loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
"-- Record dump end --\n\n");
}
-
static bool
loongarch_reloc_is_fatal (struct bfd_link_info *info,
bfd *input_bfd,
@@ -1945,8 +1948,27 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
return fatal;
}
-
-
+#define RELOCATE_CALC_PC32_HI20(relocation, pc) \
+ ({ \
+ bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \
+ pc = pc & (~(bfd_vma)0xfff); \
+ if (lo > 0x7ff) \
+ { \
+ relocation += 0x1000; \
+ } \
+ relocation &= ~(bfd_vma)0xfff; \
+ relocation -= pc; \
+ })
+
+#define RELOCATE_CALC_PC64_HI32(relocation, pc) \
+ ({ \
+ bfd_vma lo = (relocation) & ((bfd_vma)0xfff); \
+ if (lo > 0x7ff) \
+ { \
+ relocation -= 0x100000000; \
+ } \
+ relocation -= (pc & ~(bfd_vma)0xffffffff); \
+ })
static int
loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
@@ -1983,8 +2005,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bool is_ie, is_undefweak, unresolved_reloc, defined_local;
bool resolved_local, resolved_dynly, resolved_to_const;
char tls_type;
- bfd_vma relocation;
- bfd_vma off, ie_off;
+ bfd_vma relocation, off, ie_off;
int i, j;
howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
@@ -2018,9 +2039,12 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
resolved_local = true;
resolved_dynly = false;
resolved_to_const = false;
+
+ /* Calc in funtion elf_link_input_bfd,
+ * if #define elf_backend_rela_normal to 1. */
if (bfd_link_relocatable (info)
&& ELF_ST_TYPE (sym->st_info) == STT_SECTION)
- rel->r_addend += sec->output_offset;
+ continue;
}
else
{
@@ -2092,7 +2116,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
resolved_to_const = true;
}
- /* The ifunc without reference does not generate plt. */
+ /* The ifunc reference generate plt. */
if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
{
defined_local = true;
@@ -2150,20 +2174,25 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
- /* Dynamic relocations are stored in
- 1. .rela.ifunc section in PIC object.
- 2. .rela.got section in dynamic executable.
- 3. .rela.iplt section in static executable. */
- if (bfd_link_pic (info))
- sreloc = htab->elf.irelifunc;
- else if (htab->elf.splt != NULL)
- sreloc = htab->elf.srelgot;
+ if (htab->elf.splt != NULL)
+ sreloc = htab->elf.srelplt;
else
sreloc = htab->elf.irelplt;
}
else if (resolved_dynly)
{
- outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
+ if (h->dynindx == -1)
+ {
+ if (h->root.type == bfd_link_hash_undefined)
+ (*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section,
+ rel->r_offset, true);
+
+ outrel.r_info = ELFNN_R_INFO (0, r_type);
+ }
+ else
+ outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
+
outrel.r_addend = rel->r_addend;
}
else
@@ -2172,7 +2201,9 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
outrel.r_addend = relocation + rel->r_addend;
}
- if (unresolved_reloc)
+ /* No alloc space of func allocate_dynrelocs. */
+ if (unresolved_reloc
+ && !(h && (h->is_weakalias || !h->dyn_relocs)))
loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
}
@@ -2341,12 +2372,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_LARCH_SOP_PUSH_PLT_PCREL:
unresolved_reloc = false;
- if (resolved_to_const)
- {
- relocation += rel->r_addend;
- break;
- }
- else if (is_undefweak)
+ if (is_undefweak)
{
i = 0, j = 0;
relocation = 0;
@@ -2427,7 +2453,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (h != NULL)
{
- off = h->got.offset;
+ off = h->got.offset & (~1);
if (off == MINUS_ONE
&& h->type != STT_GNU_IFUNC)
@@ -2455,79 +2481,76 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (htab->elf.splt != NULL)
{
/* Section .plt header is 2 times of plt entry. */
- off = sec_addr(htab->elf.sgotplt) + off
- - sec_addr(htab->elf.sgot);
+ off = sec_addr (htab->elf.sgotplt) + off
+ - sec_addr (htab->elf.sgot);
}
else
{
/* Section iplt not has plt header. */
- off = sec_addr(htab->elf.igotplt) + off
- - sec_addr(htab->elf.sgot);
+ off = sec_addr (htab->elf.igotplt) + off
+ - sec_addr (htab->elf.sgot);
}
}
- if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn, is_pic, h)
- || (is_pic && SYMBOL_REFERENCES_LOCAL (info, h)))
+ if ((h->got.offset & 1) == 0)
{
- /* This is actually a static link, or it is a
- -Bsymbolic link and the symbol is defined
- locally, or the symbol was forced to be local
- because of a version file. We must initialize
- this entry in the global offset table. Since the
- offset must always be a multiple of the word size,
- we use the least significant bit to record whether
- we have initialized it already.
-
- When doing a dynamic link, we create a .rela.got
- relocation entry to initialize the value. This
- is done in the finish_dynamic_symbol routine. */
-
- if (resolved_dynly)
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
+ bfd_link_pic (info), h)
+ && ((bfd_link_pic (info)
+ && SYMBOL_REFERENCES_LOCAL (info, h))))
{
- fatal = (loongarch_reloc_is_fatal
- (info, input_bfd, input_section, rel, howto,
- bfd_reloc_dangerous, is_undefweak, name,
- "Internal: here shouldn't dynamic."));
- }
+ /* This is actually a static link, or it is a
+ -Bsymbolic link and the symbol is defined
+ locally, or the symbol was forced to be local
+ because of a version file. We must initialize
+ this entry in the global offset table. Since the
+ offset must always be a multiple of the word size,
+ we use the least significant bit to record whether
+ we have initialized it already.
+
+ When doing a dynamic link, we create a rela.got
+ relocation entry to initialize the value. This
+ is done in the finish_dynamic_symbol routine. */
+
+ if (resolved_dynly)
+ {
+ fatal = (loongarch_reloc_is_fatal
+ (info, input_bfd, input_section, rel, howto,
+ bfd_reloc_dangerous, is_undefweak, name,
+ "Internal: here shouldn't dynamic."));
+ }
- if (!(defined_local || resolved_to_const))
- {
- fatal = (loongarch_reloc_is_fatal
- (info, input_bfd, input_section, rel, howto,
- bfd_reloc_undefined, is_undefweak, name,
- "Internal: "));
- break;
- }
+ if (!(defined_local || resolved_to_const))
+ {
+ fatal = (loongarch_reloc_is_fatal
+ (info, input_bfd, input_section, rel, howto,
+ bfd_reloc_undefined, is_undefweak, name,
+ "Internal: "));
+ break;
+ }
- if ((off & 1) != 0)
- off &= ~1;
- else
- {
- /* The pr21964-4. Create relocate entry. */
- if (is_pic && h->start_stop)
+ asection *s;
+ Elf_Internal_Rela outrel;
+ /* We need to generate a R_LARCH_RELATIVE reloc
+ for the dynamic linker. */
+ s = htab->elf.srelgot;
+ if (!s)
{
- asection *s;
- Elf_Internal_Rela outrel;
- /* We need to generate a R_LARCH_RELATIVE reloc
- for the dynamic linker. */
- s = htab->elf.srelgot;
- if (!s)
- {
- fatal = loongarch_reloc_is_fatal (info, input_bfd,
- input_section, rel, howto,
- bfd_reloc_notsupported, is_undefweak, name,
- "Internal: '.rel.got' not represent");
- break;
- }
-
- outrel.r_offset = sec_addr (got) + off;
- outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
- outrel.r_addend = relocation; /* Link-time addr. */
- loongarch_elf_append_rela (output_bfd, s, &outrel);
+ fatal = loongarch_reloc_is_fatal
+ (info, input_bfd,
+ input_section, rel, howto,
+ bfd_reloc_notsupported, is_undefweak, name,
+ "Internal: '.rel.got' not represent");
+ break;
}
- bfd_put_NN (output_bfd, relocation, got->contents + off);
- h->got.offset |= 1;
+
+ outrel.r_offset = sec_addr (got) + off;
+ outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
+ outrel.r_addend = relocation; /* Link-time addr. */
+ loongarch_elf_append_rela (output_bfd, s, &outrel);
}
+ bfd_put_NN (output_bfd, relocation, got->contents + off);
+ h->got.offset |= 1;
}
}
else
@@ -2541,7 +2564,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
break;
}
- off = local_got_offsets[r_symndx];
+ off = local_got_offsets[r_symndx] & (~1);
if (off == MINUS_ONE)
{
@@ -2555,9 +2578,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* The offset must always be a multiple of the word size.
So, we can use the least significant bit to record
whether we have already processed this entry. */
- if ((off & 1) != 0)
- off &= ~1;
- else
+ if (local_got_offsets[r_symndx] == 0)
{
if (is_pic)
{
@@ -2586,160 +2607,519 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
}
relocation = off;
+
break;
case R_LARCH_SOP_PUSH_TLS_GOT:
case R_LARCH_SOP_PUSH_TLS_GD:
- if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
- is_ie = true;
+ {
+ unresolved_reloc = false;
+ if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
+ is_ie = true;
+
+ bfd_vma got_off = 0;
+ if (h != NULL)
+ {
+ got_off = h->got.offset;
+ h->got.offset |= 1;
+ }
+ else
+ {
+ got_off = local_got_offsets[r_symndx];
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ BFD_ASSERT (got_off != MINUS_ONE);
+
+ ie_off = 0;
+ tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+ if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
+ ie_off = 2 * GOT_ENTRY_SIZE;
+
+ if ((got_off & 1) == 0)
+ {
+ Elf_Internal_Rela rela;
+ asection *srel = htab->elf.srelgot;
+ bfd_vma tls_block_off = 0;
+
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ BFD_ASSERT (elf_hash_table (info)->tls_sec);
+ tls_block_off = relocation
+ - elf_hash_table (info)->tls_sec->vma;
+ }
+
+ if (tls_type & GOT_TLS_GD)
+ {
+ rela.r_offset = sec_addr (got) + got_off;
+ rela.r_addend = 0;
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ /* Local sym, used in exec, set module id 1. */
+ if (bfd_link_executable (info))
+ bfd_put_NN (output_bfd, 1, got->contents + got_off);
+ else
+ {
+ rela.r_info = ELFNN_R_INFO (0,
+ R_LARCH_TLS_DTPMODNN);
+ loongarch_elf_append_rela (output_bfd, srel, &rela);
+ }
+
+ bfd_put_NN (output_bfd, tls_block_off,
+ got->contents + got_off + GOT_ENTRY_SIZE);
+ }
+ /* Dynamic resolved. */
+ else
+ {
+ /* Dynamic relocate module id. */
+ rela.r_info = ELFNN_R_INFO (h->dynindx,
+ R_LARCH_TLS_DTPMODNN);
+ loongarch_elf_append_rela (output_bfd, srel, &rela);
+
+ /* Dynamic relocate offset of block. */
+ rela.r_offset += GOT_ENTRY_SIZE;
+ rela.r_info = ELFNN_R_INFO (h->dynindx,
+ R_LARCH_TLS_DTPRELNN);
+ loongarch_elf_append_rela (output_bfd, srel, &rela);
+ }
+ }
+ if (tls_type & GOT_TLS_IE)
+ {
+ rela.r_offset = sec_addr (got) + got_off + ie_off;
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ /* Local sym, used in exec, set module id 1. */
+ if (!bfd_link_executable (info))
+ {
+ rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
+ rela.r_addend = tls_block_off;
+ loongarch_elf_append_rela (output_bfd, srel, &rela);
+ }
+
+ bfd_put_NN (output_bfd, tls_block_off,
+ got->contents + got_off + ie_off);
+ }
+ /* Dynamic resolved. */
+ else
+ {
+ /* Dynamic relocate offset of block. */
+ rela.r_info = ELFNN_R_INFO (h->dynindx,
+ R_LARCH_TLS_TPRELNN);
+ rela.r_addend = 0;
+ loongarch_elf_append_rela (output_bfd, srel, &rela);
+ }
+ }
+ }
+
+ relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
+ }
+ break;
+
+ /* New reloc types. */
+ case R_LARCH_B21:
+ case R_LARCH_B26:
+ case R_LARCH_B16:
unresolved_reloc = false;
+ if (is_undefweak)
+ {
+ relocation = 0;
+ }
- if (rel->r_addend != 0)
+ if (resolved_local)
{
- fatal = (loongarch_reloc_is_fatal
- (info, input_bfd, input_section, rel, howto,
- bfd_reloc_notsupported, is_undefweak, name,
- "Shouldn't be with r_addend."));
+ relocation -= pc;
+ relocation += rel->r_addend;
+ }
+ else if (resolved_dynly)
+ {
+ BFD_ASSERT (h
+ && (h->plt.offset != MINUS_ONE
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ && rel->r_addend == 0);
+ if (h && h->plt.offset == MINUS_ONE
+ && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ {
+ relocation -= pc;
+ relocation += rel->r_addend;
+ }
+ else
+ relocation = sec_addr (plt) + h->plt.offset - pc;
+ }
+
+ break;
+
+ case R_LARCH_ABS_HI20:
+ case R_LARCH_ABS_LO12:
+ case R_LARCH_ABS64_LO20:
+ case R_LARCH_ABS64_HI12:
+ BFD_ASSERT (!is_pic);
+
+ if (is_undefweak)
+ {
+ BFD_ASSERT (resolved_dynly);
+ relocation = 0;
break;
}
+ else if (resolved_to_const || resolved_local)
+ {
+ relocation += rel->r_addend;
+ }
+ else if (resolved_dynly)
+ {
+ unresolved_reloc = false;
+ BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
+ && rel->r_addend == 0);
+ relocation = sec_addr (plt) + h->plt.offset;
+ }
+ break;
+
+ case R_LARCH_PCALA_HI20:
+ unresolved_reloc = false;
+ if (h && h->plt.offset != MINUS_ONE)
+ relocation = sec_addr (plt) + h->plt.offset;
+ else
+ relocation += rel->r_addend;
+
+ RELOCATE_CALC_PC32_HI20 (relocation, pc);
+
+ break;
+
+ case R_LARCH_PCALA_LO12:
+ /* Not support if sym_addr in 2k page edge.
+ pcalau12i pc_hi20 (sym_addr)
+ ld.w/d pc_lo12 (sym_addr)
+ ld.w/d pc_lo12 (sym_addr + x)
+ ...
+ can not calc correct address
+ if sym_addr < 0x800 && sym_addr + x >= 0x800. */
+
+ if (h && h->plt.offset != MINUS_ONE)
+ relocation = sec_addr (plt) + h->plt.offset;
+ else
+ relocation += rel->r_addend;
- if (resolved_to_const && is_undefweak && h->dynindx != -1)
{
- /* What if undefweak? Let rtld make a decision. */
- resolved_to_const = resolved_local = false;
- resolved_dynly = true;
+ relocation &= 0xfff;
+ /* Signed extend. */
+ relocation = (relocation ^ 0x800) - 0x800;
+
+ /* For 2G jump, generate pcalau12i, jirl. */
+ /* If use jirl, turns to R_LARCH_B16. */
+ uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
+ if ((insn & 0x4c000000) == 0x4c000000)
+ {
+ rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16);
+ howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
+ }
}
+ break;
- if (resolved_to_const)
+ case R_LARCH_PCALA64_LO20:
+ case R_LARCH_PCALA64_HI12:
+ if (h && h->plt.offset != MINUS_ONE)
{
- fatal = (loongarch_reloc_is_fatal
- (info, input_bfd, input_section, rel, howto,
- bfd_reloc_notsupported, is_undefweak, name,
- "Internal: Shouldn't be resolved to const."));
- break;
+ BFD_ASSERT (rel->r_addend == 0);
+ relocation = sec_addr (plt) + h->plt.offset;
+ }
+ else
+ relocation += rel->r_addend;
+
+ RELOCATE_CALC_PC64_HI32 (relocation, pc);
+
+ break;
+
+ case R_LARCH_GOT_PC_HI20:
+ case R_LARCH_GOT64_HI20:
+ /* Calc got offset. */
+ {
+ unresolved_reloc = false;
+ BFD_ASSERT (rel->r_addend == 0);
+
+ bfd_vma got_off = 0;
+ if (h != NULL)
+ {
+ /* GOT ref or ifunc. */
+ BFD_ASSERT (h->got.offset != MINUS_ONE
+ || h->type == STT_GNU_IFUNC);
+
+ got_off = h->got.offset & (~(bfd_vma)1);
+ /* Hidden symbol not has got entry,
+ * only got.plt entry so it is (plt - got). */
+ if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
+ {
+ bfd_vma idx;
+ if (htab->elf.splt != NULL)
+ {
+ idx = (h->plt.offset - PLT_HEADER_SIZE)
+ / PLT_ENTRY_SIZE;
+ got_off = sec_addr (htab->elf.sgotplt)
+ + GOTPLT_HEADER_SIZE
+ + (idx * GOT_ENTRY_SIZE)
+ - sec_addr (htab->elf.sgot);
+ }
+ else
+ {
+ idx = h->plt.offset / PLT_ENTRY_SIZE;
+ got_off = sec_addr (htab->elf.sgotplt)
+ + (idx * GOT_ENTRY_SIZE)
+ - sec_addr (htab->elf.sgot);
+ }
+ }
+
+ if ((h->got.offset & 1) == 0)
+ {
+ /* We need to generate a R_LARCH_RELATIVE reloc once
+ * in loongarch_elf_finish_dynamic_symbol or now,
+ * call finish_dyn && nopic
+ * or !call finish_dyn && pic. */
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
+ bfd_link_pic (info),
+ h)
+ && bfd_link_pic (info)
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ Elf_Internal_Rela rela;
+ rela.r_offset = sec_addr (got) + got_off;
+ rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
+ rela.r_addend = relocation;
+ loongarch_elf_append_rela (output_bfd,
+ htab->elf.srelgot, &rela);
+ }
+ h->got.offset |= 1;
+ }
+ }
+ else
+ {
+ BFD_ASSERT (local_got_offsets
+ && local_got_offsets[r_symndx] != MINUS_ONE);
+
+ got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
+ if ((local_got_offsets[r_symndx] & 1) == 0)
+ {
+ if (bfd_link_pic (info))
+ {
+ Elf_Internal_Rela rela;
+ rela.r_offset = sec_addr (got) + got_off;
+ rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
+ rela.r_addend = relocation;
+ loongarch_elf_append_rela (output_bfd,
+ htab->elf.srelgot, &rela);
+ }
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ bfd_put_NN (output_bfd, relocation, got->contents + got_off);
+
+ relocation = got_off + sec_addr (got);
}
+ if (r_type == R_LARCH_GOT_PC_HI20)
+ RELOCATE_CALC_PC32_HI20 (relocation, pc);
+
+ break;
+
+ case R_LARCH_GOT_PC_LO12:
+ case R_LARCH_GOT64_PC_LO20:
+ case R_LARCH_GOT64_PC_HI12:
+ case R_LARCH_GOT64_LO12:
+ case R_LARCH_GOT64_LO20:
+ case R_LARCH_GOT64_HI12:
+ {
+ unresolved_reloc = false;
+ bfd_vma got_off;
+ if (h)
+ got_off = h->got.offset & (~(bfd_vma)1);
+ else
+ got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
+
+ if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
+ {
+ bfd_vma idx;
+ if (htab->elf.splt != NULL)
+ idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
+ else
+ idx = h->plt.offset / PLT_ENTRY_SIZE;
+
+ got_off = sec_addr (htab->elf.sgotplt)
+ + GOTPLT_HEADER_SIZE
+ + (idx * GOT_ENTRY_SIZE)
+ - sec_addr (htab->elf.sgot);
+ }
+ relocation = got_off + sec_addr (got);
+ }
+
+ if (r_type == R_LARCH_GOT_PC_LO12)
+ relocation &= (bfd_vma)0xfff;
+ else if (r_type == R_LARCH_GOT64_PC_LO20
+ || r_type == R_LARCH_GOT64_PC_HI12)
+ RELOCATE_CALC_PC64_HI32 (relocation, pc);
+
+ break;
+
+ case R_LARCH_TLS_LE_HI20:
+ case R_LARCH_TLS_LE_LO12:
+ case R_LARCH_TLS_LE64_LO20:
+ case R_LARCH_TLS_LE64_HI12:
+ BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
+
+ relocation -= elf_hash_table (info)->tls_sec->vma;
+ break;
+
+ /* TLS IE LD/GD process separately is troublesome.
+ When a symbol is both ie and LD/GD, h->got.off |= 1
+ make only one type be relocated. We must use
+ h->got.offset |= 1 and h->got.offset |= 2
+ diff IE and LD/GD. And all (got_off & (~(bfd_vma)1))
+ (IE LD/GD and reusable GOT reloc) must change to
+ (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
+ as a tag.
+ Now, LD and GD is both GOT_TLS_GD type, LD seems to
+ can be omitted. */
+ case R_LARCH_TLS_IE_PC_HI20:
+ case R_LARCH_TLS_IE64_HI20:
+ case R_LARCH_TLS_LD_PC_HI20:
+ case R_LARCH_TLS_LD64_HI20:
+ case R_LARCH_TLS_GD_PC_HI20:
+ case R_LARCH_TLS_GD64_HI20:
+ BFD_ASSERT (rel->r_addend == 0);
+ unresolved_reloc = false;
+
+ if (r_type == R_LARCH_TLS_IE_PC_HI20
+ || r_type == R_LARCH_TLS_IE64_HI20)
+ is_ie = true;
+
+ bfd_vma got_off = 0;
if (h != NULL)
{
- off = h->got.offset;
+ got_off = h->got.offset;
h->got.offset |= 1;
}
else
{
- off = local_got_offsets[r_symndx];
+ got_off = local_got_offsets[r_symndx];
local_got_offsets[r_symndx] |= 1;
}
- if (off == MINUS_ONE)
- {
- fatal = (loongarch_reloc_is_fatal
- (info, input_bfd, input_section, rel, howto,
- bfd_reloc_notsupported, is_undefweak, name,
- "Internal: TLS GOT entry doesn't represent."));
- break;
- }
-
- tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+ BFD_ASSERT (got_off != MINUS_ONE);
- /* If this symbol is referenced by both GD and IE TLS, the IE
- reference's GOT slot follows the GD reference's slots. */
ie_off = 0;
+ tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
ie_off = 2 * GOT_ENTRY_SIZE;
- if ((off & 1) != 0)
- off &= ~1;
- else
+ if ((got_off & 1) == 0)
{
+ Elf_Internal_Rela rela;
+ asection *relgot = htab->elf.srelgot;
bfd_vma tls_block_off = 0;
- Elf_Internal_Rela outrel;
- if (resolved_local)
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
{
- if (!elf_hash_table (info)->tls_sec)
- {
- fatal = (loongarch_reloc_is_fatal
- (info, input_bfd, input_section, rel, howto,
- bfd_reloc_notsupported, is_undefweak, name,
- "Internal: TLS sec not represent."));
- break;
- }
- tls_block_off =
- relocation - elf_hash_table (info)->tls_sec->vma;
+ BFD_ASSERT (elf_hash_table (info)->tls_sec);
+ tls_block_off = relocation
+ - elf_hash_table (info)->tls_sec->vma;
}
if (tls_type & GOT_TLS_GD)
{
- outrel.r_offset = sec_addr (got) + off;
- outrel.r_addend = 0;
- bfd_put_NN (output_bfd, 0, got->contents + off);
- if (resolved_local && bfd_link_executable (info))
- bfd_put_NN (output_bfd, 1, got->contents + off);
- else if (resolved_local /* && !bfd_link_executable (info) */)
- {
- outrel.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
- loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
- &outrel);
- }
- else /* if (resolved_dynly) */
+ rela.r_offset = sec_addr (got) + got_off;
+ rela.r_addend = 0;
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
{
- outrel.r_info =
- ELFNN_R_INFO (h->dynindx, R_LARCH_TLS_DTPMODNN);
- loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
- &outrel);
- }
+ /* Local sym, used in exec, set module id 1. */
+ if (bfd_link_executable (info))
+ bfd_put_NN (output_bfd, 1, got->contents + got_off);
+ else
+ {
+ rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
+ loongarch_elf_append_rela (output_bfd, relgot, &rela);
+ }
- outrel.r_offset += GOT_ENTRY_SIZE;
- bfd_put_NN (output_bfd, tls_block_off,
- got->contents + off + GOT_ENTRY_SIZE);
- if (resolved_local)
- /* DTPREL known. */;
- else /* if (resolved_dynly) */
+ bfd_put_NN (output_bfd, tls_block_off,
+ got->contents + got_off + GOT_ENTRY_SIZE);
+ }
+ /* Dynamic resolved. */
+ else
{
- outrel.r_info =
- ELFNN_R_INFO (h->dynindx, R_LARCH_TLS_DTPRELNN);
- loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
- &outrel);
+ /* Dynamic relocate module id. */
+ rela.r_info = ELFNN_R_INFO (h->dynindx,
+ R_LARCH_TLS_DTPMODNN);
+ loongarch_elf_append_rela (output_bfd, relgot, &rela);
+
+ /* Dynamic relocate offset of block. */
+ rela.r_offset += GOT_ENTRY_SIZE;
+ rela.r_info = ELFNN_R_INFO (h->dynindx,
+ R_LARCH_TLS_DTPRELNN);
+ loongarch_elf_append_rela (output_bfd, relgot, &rela);
}
}
-
if (tls_type & GOT_TLS_IE)
{
- outrel.r_offset = sec_addr (got) + off + ie_off;
- bfd_put_NN (output_bfd, tls_block_off,
- got->contents + off + ie_off);
- if (resolved_local && bfd_link_executable (info))
- /* TPREL known. */;
- else if (resolved_local /* && !bfd_link_executable (info) */)
+ rela.r_offset = sec_addr (got) + got_off + ie_off;
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
{
- outrel.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
- outrel.r_addend = tls_block_off;
- loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
- &outrel);
- }
- else /* if (resolved_dynly) */
- {
- /* Static linking has no .dynsym table. */
- if (!htab->elf.dynamic_sections_created)
- {
- outrel.r_info =
- ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
- outrel.r_addend = 0;
- }
- else
+ /* Local sym, used in exec, set module id 1. */
+ if (!bfd_link_executable (info))
{
- outrel.r_info =
- ELFNN_R_INFO (h->dynindx, R_LARCH_TLS_TPRELNN);
- outrel.r_addend = 0;
+ rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
+ rela.r_addend = tls_block_off;
+ loongarch_elf_append_rela (output_bfd, relgot, &rela);
}
- loongarch_elf_append_rela (output_bfd, htab->elf.srelgot,
- &outrel);
+
+ bfd_put_NN (output_bfd, tls_block_off,
+ got->contents + got_off + ie_off);
+ }
+ /* Dynamic resolved. */
+ else
+ {
+ /* Dynamic relocate offset of block. */
+ rela.r_info = ELFNN_R_INFO (h->dynindx,
+ R_LARCH_TLS_TPRELNN);
+ rela.r_addend = 0;
+ loongarch_elf_append_rela (output_bfd, relgot, &rela);
}
}
}
+ relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got)
+ + (is_ie ? ie_off : 0);
+
+ if (r_type == R_LARCH_TLS_LD_PC_HI20
+ || r_type == R_LARCH_TLS_GD_PC_HI20
+ || r_type == R_LARCH_TLS_IE_PC_HI20)
+ RELOCATE_CALC_PC32_HI20 (relocation, pc);
- relocation = off + (is_ie ? ie_off : 0);
+ break;
+
+ case R_LARCH_TLS_IE_PC_LO12:
+ case R_LARCH_TLS_IE64_PC_LO20:
+ case R_LARCH_TLS_IE64_PC_HI12:
+ case R_LARCH_TLS_IE64_LO12:
+ case R_LARCH_TLS_IE64_LO20:
+ case R_LARCH_TLS_IE64_HI12:
+ unresolved_reloc = false;
+
+ if (h)
+ relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)3));
+ else
+ relocation = sec_addr (got)
+ + (local_got_offsets[r_symndx] & (~(bfd_vma)3));
+
+ tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+ /* Use both TLS_GD and TLS_IE. */
+ if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
+ relocation += 2 * GOT_ENTRY_SIZE;
+
+ if (r_type == R_LARCH_TLS_IE_PC_LO12)
+ relocation &= (bfd_vma)0xfff;
+ else if (r_type == R_LARCH_TLS_IE64_PC_LO20
+ || r_type == R_LARCH_TLS_IE64_PC_HI12)
+ RELOCATE_CALC_PC64_HI32 (relocation, pc);
+
+ break;
+
+ case R_LARCH_RELAX:
break;
default:
@@ -2759,7 +3139,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (_bfd_elf_section_offset (output_bfd, info, input_section,
rel->r_offset) == MINUS_ONE)
/* WHY? May because it's invalid so skip checking.
- But why dynamic reloc a invalid section? */
+ But why dynamic reloc a invalid section? */
break;
if (input_section->output_section->flags & SEC_DEBUGGING)
@@ -2825,7 +3205,6 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
fatal = true;
- break;
}
return !fatal;
@@ -2889,27 +3268,15 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
for (i = 0; i < PLT_ENTRY_INSNS; i++)
bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
- /* Fill in the initial value of the .got.plt entry. */
+ /* Fill in the initial value of the got.plt entry. */
loc = gotplt->contents + (got_address - sec_addr (gotplt));
bfd_put_NN (output_bfd, sec_addr (plt), loc);
rela.r_offset = got_address;
- /* TRUE if this is a PLT reference to a local IFUNC. */
- if (PLT_LOCAL_IFUNC_P(info, h))
- {
- rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
- rela.r_addend = (h->root.u.def.value
- + h->root.u.def.section->output_section->vma
- + h->root.u.def.section->output_offset);
- }
- else
- {
- /* Fill in the entry in the .rela.plt section. */
- rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
- rela.r_addend = 0;
- }
-
+ /* Fill in the entry in the rela.plt section. */
+ rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
+ rela.r_addend = 0;
loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
bed->s->swap_reloca_out (output_bfd, &rela, loc);
@@ -2930,15 +3297,14 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
if (h->got.offset != MINUS_ONE
/* TLS got entry have been handled in elf_relocate_section. */
&& !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
- /* have allocated got entry but not allocated rela before. */
+ /* Have allocated got entry but not allocated rela before. */
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
{
asection *sgot, *srela;
Elf_Internal_Rela rela;
- bfd_vma off = h->got.offset & ~(bfd_vma) 1;
+ bfd_vma off = h->got.offset & ~(bfd_vma)1;
/* This symbol has an entry in the GOT. Set it up. */
-
sgot = htab->elf.sgot;
srela = htab->elf.srelgot;
BFD_ASSERT (sgot && srela);
@@ -2963,7 +3329,6 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
}
else
{
- BFD_ASSERT ((h->got.offset & 1) == 0);
BFD_ASSERT (h->dynindx != -1);
rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
rela.r_addend = 0;
@@ -2993,7 +3358,6 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
}
else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
{
- BFD_ASSERT (h->got.offset & 1 /* Has been filled in addr. */);
asection *sec = h->root.u.def.section;
rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
rela.r_addend = (h->root.u.def.value + sec->output_section->vma
@@ -3001,7 +3365,6 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
}
else
{
- BFD_ASSERT ((h->got.offset & 1) == 0);
BFD_ASSERT (h->dynindx != -1);
rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
rela.r_addend = 0;
@@ -3010,24 +3373,6 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
loongarch_elf_append_rela (output_bfd, srela, &rela);
}
- if (h->needs_copy)
- {
- Elf_Internal_Rela rela;
- asection *s;
-
- /* This symbols needs a copy reloc. Set it up. */
- BFD_ASSERT (h->dynindx != -1);
-
- rela.r_offset = sec_addr (h->root.u.def.section) + h->root.u.def.value;
- rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_COPY);
- rela.r_addend = 0;
- if (h->root.u.def.section == htab->elf.sdynrelro)
- s = htab->elf.sreldynrelro;
- else
- s = htab->elf.srelbss;
- loongarch_elf_append_rela (output_bfd, s, &rela);
- }
-
/* Mark some specially defined symbols as absolute. */
if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
sym->st_shndx = SHN_ABS;
@@ -3337,7 +3682,6 @@ loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
#define PRPSINFO_OFFSET_PR_PS_ARGS 0x38
#define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50
-
static bool
loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 4424969e579..1f6346ef5f3 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -35,27 +35,30 @@ typedef struct loongarch_reloc_howto_type_struct
reloc_howto_type howto;
bfd_reloc_code_real_type bfd_type;
bool (*adjust_reloc_bits)(reloc_howto_type *, bfd_vma *);
-}loongarch_reloc_howto_type;
+ const char *larch_reloc_type_name;
+} loongarch_reloc_howto_type;
#define LOONGARCH_DEFAULT_HOWTO(r_name) \
{ HOWTO (R_LARCH_##r_name, 0, 4, 32, false, 0, complain_overflow_signed, \
bfd_elf_generic_reloc, "R_LARCH_" #r_name, false, 0, ALL_ONES, \
- false), BFD_RELOC_LARCH_##r_name, NULL }
+ false), BFD_RELOC_LARCH_##r_name, NULL, NULL }
#define LOONGARCH_HOWTO(type, right, size, bits, pcrel, left, ovf, func, \
- name, inplace, src_mask, dst_mask, pcrel_off, btype, afunc) \
+ name, inplace, src_mask, dst_mask, pcrel_off, btype, afunc,lname) \
{ HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \
- inplace, src_mask, dst_mask, pcrel_off), btype, afunc }
+ inplace, src_mask, dst_mask, pcrel_off), btype, afunc, lname }
#define LOONGARCH_EMPTY_HOWTO(C) \
- { EMPTY_HOWTO(C), BFD_RELOC_NONE, NULL }
-
-bool loongarch_gen_adjust_reloc_bits (reloc_howto_type *howto, bfd_vma *val);
-bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto,
- bfd_vma *fix_val);
-bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto,
- bfd_vma *val);
+ { EMPTY_HOWTO (C), BFD_RELOC_NONE, NULL, NULL }
+static bool
+reloc_bits (reloc_howto_type *howto, bfd_vma *val);
+static bool
+reloc_bits_b16 (reloc_howto_type *howto, bfd_vma *fix_val);
+static bool
+reloc_bits_b21 (reloc_howto_type *howto, bfd_vma *fix_val);
+static bool
+reloc_bits_b26 (reloc_howto_type *howto, bfd_vma *val);
/* This does not include any relocation information, but should be
good enough for GDB or objdump to read the file. */
@@ -76,7 +79,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
0, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_NONE, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
/* 32 bit relocation. */
LOONGARCH_HOWTO (R_LARCH_32, /* type (1). */
@@ -93,7 +97,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_32, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
/* 64 bit relocation. */
LOONGARCH_HOWTO (R_LARCH_64, /* type (2). */
@@ -110,7 +115,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_64, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_RELATIVE, /* type (3). */
0, /* rightshift */
@@ -126,7 +132,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_NONE, /* undefined? */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_COPY, /* type (4). */
0, /* rightshift */
@@ -141,8 +148,9 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
0, /* src_mask */
0, /* dst_mask */
false, /* pcrel_offset */
- BFD_RELOC_NONE, /* undefined? */
- NULL), /* adjust_reloc_bits */
+ BFD_RELOC_NONE, /* undefined? */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */
0, /* rightshift */
@@ -157,8 +165,9 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
0, /* src_mask */
0, /* dst_mask */
false, /* pcrel_offset */
- BFD_RELOC_NONE, /* undefined? */
- NULL), /* adjust_reloc_bits */
+ BFD_RELOC_NONE, /* undefined? */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
/* Dynamic TLS relocations. */
LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */
@@ -175,7 +184,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_TLS_DTPMOD32, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */
0, /* rightshift */
@@ -191,7 +201,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_TLS_DTPMOD64, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */
0, /* rightshift */
@@ -207,7 +218,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_TLS_DTPREL32, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */
0, /* rightshift */
@@ -223,7 +235,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_TLS_DTPREL64, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */
0, /* rightshift */
@@ -239,7 +252,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_TLS_TPREL32, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */
0, /* rightshift */
@@ -255,7 +269,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_TLS_TPREL64, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_IRELATIVE, /* type (12). */
0, /* rightshift */
@@ -271,63 +286,67 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_NONE, /* undefined? */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_EMPTY_HOWTO(13),
- LOONGARCH_EMPTY_HOWTO(14),
- LOONGARCH_EMPTY_HOWTO(15),
- LOONGARCH_EMPTY_HOWTO(16),
- LOONGARCH_EMPTY_HOWTO(17),
- LOONGARCH_EMPTY_HOWTO(18),
- LOONGARCH_EMPTY_HOWTO(19),
+ LOONGARCH_EMPTY_HOWTO (13),
+ LOONGARCH_EMPTY_HOWTO (14),
+ LOONGARCH_EMPTY_HOWTO (15),
+ LOONGARCH_EMPTY_HOWTO (16),
+ LOONGARCH_EMPTY_HOWTO (17),
+ LOONGARCH_EMPTY_HOWTO (18),
+ LOONGARCH_EMPTY_HOWTO (19),
LOONGARCH_HOWTO (R_LARCH_MARK_LA, /* type (20). */
- 0, /* rightshift. */
- 0, /* size. */
- 0, /* bitsize. */
+ 0, /* rightshift. */
+ 0, /* size. */
+ 0, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_MARK_LA", /* name. */
- false, /* partial_inplace. */
+ false, /* partial_inplace. */
0, /* src_mask. */
0, /* dst_mask. */
false, /* pcrel_offset */
BFD_RELOC_LARCH_MARK_LA, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_MARK_PCREL, /* type (21). */
- 0, /* rightshift. */
- 0, /* size. */
- 0, /* bitsize. */
+ 0, /* rightshift. */
+ 0, /* size. */
+ 0, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_MARK_PCREL", /* name. */
- false, /* partial_inplace. */
+ false, /* partial_inplace. */
0, /* src_mask. */
0, /* dst_mask. */
false, /* pcrel_offset */
BFD_RELOC_LARCH_MARK_PCREL, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */
- 2, /* rightshift. */
- 4, /* size. */
- 32, /* bitsize. */
+ 2, /* rightshift. */
+ 4, /* size. */
+ 32, /* bitsize. */
true /* FIXME: somewhat use this. */, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_PUSH_PCREL", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_PUSH_PCREL", /* name. */
+ false, /* partial_inplace. */
0x03ffffff, /* src_mask. */
0x03ffffff, /* dst_mask. */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_PUSH_PCREL, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
/* type 23-37. */
LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_ABSOLUTE),
@@ -347,343 +366,984 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
LOONGARCH_DEFAULT_HOWTO (SOP_IF_ELSE),
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */
- 0, /* rightshift. */
- 4, /* size. */
- 5, /* bitsize. */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 5, /* bitsize. */
false, /* pc_relative. */
- 10, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_S_10_5", /* name. */
- false, /* partial_inplace. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_POP_32_S_10_5", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
0x7c00, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_S_10_5, /* bfd_reloc_code_real_type */
- loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+ reloc_bits, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */
- 0, /* rightshift. */
- 4, /* size. */
- 12, /* bitsize. */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
false, /* pc_relative. */
- 10, /* bitpos. */
- complain_overflow_unsigned, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_U_10_12", /* name. */
- false, /* partial_inplace. */
+ 10, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_POP_32_U_10_12", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
0x3ffc00, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_U_10_12, /* bfd_reloc_code_real_type */
- loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+ reloc_bits, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */
- 0, /* rightshift. */
- 4, /* size. */
- 12, /* bitsize. */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
false, /* pc_relative. */
- 10, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_S_10_12", /* name. */
- false, /* partial_inplace. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_POP_32_S_10_12", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
0x3ffc00, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_S_10_12, /* bfd_reloc_code_real_type */
- loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+ reloc_bits, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */
- 0, /* rightshift. */
- 4, /* size. */
- 16, /* bitsize. */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 16, /* bitsize. */
false, /* pc_relative. */
- 10, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_S_10_16", /* name. */
- false, /* partial_inplace. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_POP_32_S_10_16", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
0x3fffc00, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_S_10_16, /* bfd_reloc_code_real_type */
- loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+ reloc_bits, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */
2, /* rightshift. */
- 4, /* size. */
- 16, /* bitsize. */
+ 4, /* size. */
+ 16, /* bitsize. */
false, /* pc_relative. */
- 10, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_S_10_16_S2", /* name. */
- false, /* partial_inplace. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_POP_32_S_10_16_S2", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
0x3fffc00, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2, /* bfd_reloc_code_real_type */
- loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+ reloc_bits_b16, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */
- 0, /* rightshift. */
- 4, /* size. */
- 20, /* bitsize. */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
false, /* pc_relative. */
- 5, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_S_5_20", /* name. */
- false, /* partial_inplace. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_POP_32_S_5_20", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
0x1ffffe0, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_S_5_20, /* bfd_reloc_code_real_type */
- loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+ reloc_bits, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2,
/* type (44). */
2, /* rightshift. */
4, /* size. */
- 21, /* bitsize. */
+ 21, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_S_0_5_10_16_S2", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_POP_32_S_0_5_10_16_S2", /* name. */
+ false, /* partial_inplace. */
0xfc0003e0, /* src_mask */
0xfc0003e0, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2,
/* bfd_reloc_code_real_type */
- loongarch_adjust_reloc_bits_l16_xx5_h5), /* adjust_reloc_bits */
+ reloc_bits_b21, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */
- 2, /* rightshift. */
- 4, /* size. */
- 26, /* bitsize. */
- false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_S_0_10_10_16_S2", /* name. */
- false, /* partial_inplace. */
- 0xfc000000, /* src_mask */
- 0xfc000000, /* dst_mask */
+ 2, /* rightshift. */
+ 4, /* size. */
+ 26, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_POP_32_S_0_10_10_16_S2", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x03ffffff, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2,
/* bfd_reloc_code_real_type */
- loongarch_adjust_reloc_bits_l16_h10), /* adjust_reloc_bits */
+ reloc_bits_b26, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */
- 0, /* rightshift. */
- 4, /* size. */
- 32, /* bitsize. */
- false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_unsigned, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_S_U", /* name. */
- false, /* partial_inplace. */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 32, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SOP_POP_32_S_U", /* name. */
+ false, /* partial_inplace. */
0xffffffff00000000, /* src_mask */
0x00000000ffffffff, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_U, /* bfd_reloc_code_real_type */
- loongarch_gen_adjust_reloc_bits), /* adjust_reloc_bits */
+ reloc_bits, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */
- 0, /* rightshift. */
- 4, /* size. */
- 8, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 8, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_ADD8", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ADD8", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_ADD8, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */
- 0, /* rightshift. */
- 4, /* size. */
- 16, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 16, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_ADD16", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ADD16", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_ADD16, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */
- 0, /* rightshift. */
- 4, /* size. */
- 24, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 24, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_ADD24", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ADD24", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_ADD24, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */
- 0, /* rightshift. */
- 4, /* size. */
- 32, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 32, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_ADD32", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ADD32", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_ADD32, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */
- 0, /* rightshift. */
- 8, /* size. */
- 64, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */
+ 0, /* rightshift. */
+ 8, /* size. */
+ 64, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_ADD64", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ADD64", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_ADD64, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */
- 0, /* rightshift. */
- 4, /* size. */
- 8, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 8, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SUB8", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SUB8", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SUB8, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */
- 0, /* rightshift. */
- 4, /* size. */
- 16, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 16, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SUB16", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SUB16", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SUB16, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */
- 0, /* rightshift. */
- 4, /* size. */
- 24, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 24, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SUB24", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SUB24", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SUB24, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */
- 0, /* rightshift. */
- 4, /* size. */
- 32, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 32, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SUB32", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SUB32", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SUB32, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */
- 0, /* rightshift. */
- 8, /* size. */
- 64, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */
+ 0, /* rightshift. */
+ 8, /* size. */
+ 64, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SUB64", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_SUB64", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
ALL_ONES, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SUB64, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT, /* type (57). */
- 0, /* rightshift. */
- 0, /* size. */
- 0, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT, /* type (57). */
+ 0, /* rightshift. */
+ 0, /* size. */
+ 0, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
- bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_GNU_VTINHERIT", /* name. */
- false, /* partial_inplace. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_GNU_VTINHERIT", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
0, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_NONE, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY, /* type (58). */
- 0, /* rightshift. */
- 0, /* size. */
- 0, /* bitsize. */
+ LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY, /* type (58). */
+ 0, /* rightshift. */
+ 0, /* size. */
+ 0, /* bitsize. */
false, /* pc_relative. */
- 0, /* bitpos. */
- complain_overflow_signed, /* complain_on_overflow. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
NULL, /* special_function. */
- "R_LARCH_GNU_VTENTRY", /* name. */
- false, /* partial_inplace. */
+ "R_LARCH_GNU_VTENTRY", /* name. */
+ false, /* partial_inplace. */
0, /* src_mask */
0, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_NONE, /* bfd_reloc_code_real_type */
- NULL), /* adjust_reloc_bits */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
+
+ LOONGARCH_EMPTY_HOWTO (59),
+ LOONGARCH_EMPTY_HOWTO (60),
+ LOONGARCH_EMPTY_HOWTO (61),
+ LOONGARCH_EMPTY_HOWTO (62),
+ LOONGARCH_EMPTY_HOWTO (63),
+
+ /* New reloc types. */
+ LOONGARCH_HOWTO (R_LARCH_B16, /* type (64). */
+ 2, /* rightshift. */
+ 4, /* size. */
+ 16, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_B16", /* name. */
+ false, /* partial_inplace. */
+ 0x3fffc00, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_B16, /* bfd_reloc_code_real_type */
+ reloc_bits_b16, /* adjust_reloc_bits */
+ "b16"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */
+ 2, /* rightshift. */
+ 4, /* size. */
+ 21, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_B21", /* name. */
+ false, /* partial_inplace. */
+ 0xfc0003e0, /* src_mask */
+ 0xfc0003e0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_B21, /* bfd_reloc_code_real_type */
+ reloc_bits_b21, /* adjust_reloc_bits */
+ "b21"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */
+ 2, /* rightshift. */
+ 4, /* size. */
+ 26, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_B26", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_B26, /* bfd_reloc_code_real_type */
+ reloc_bits_b26, /* adjust_reloc_bits */
+ "b26"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ABS_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_ABS_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "abs_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_ABS_LO12, /* type (68). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ABS_LO12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_ABS_LO12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "abs_lo12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_ABS64_LO20, /* type (69). */
+ 32, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ABS64_LO20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_ABS64_LO20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "abs64_lo20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_ABS64_HI12, /* type (70). */
+ 52, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_ABS64_HI12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_ABS64_HI12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "abs64_hi12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_PCALA_HI20, /* type (71). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_PCALA_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_PCALA_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "pc_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_PCALA_LO12, /* type (72). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_PCALA_LO12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_PCALA_LO12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "pc_lo12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_PCALA64_LO20, /* type (73). */
+ 32, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_PCALA64_LO20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_PCALA64_LO20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "pc64_lo20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_PCALA64_HI12, /* type (74). */
+ 52, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_PCALA64_HI12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_PCALA64_HI12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "pc64_hi12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_GOT_PC_HI20, /* type (75). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_GOT_PC_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_GOT_PC_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "got_pc_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_GOT_PC_LO12, /* type (76). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_GOT_PC_LO12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_GOT_PC_LO12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "got_pc_lo12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_GOT64_PC_LO20, /* type (77). */
+ 32, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_GOT64_PC_LO20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_GOT64_PC_LO20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "got64_pc_lo20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_GOT64_PC_HI12, /* type (78). */
+ 52, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_GOT64_PC_HI12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_GOT64_PC_HI12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "got64_pc_hi12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_GOT64_HI20, /* type (79). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_GOT64_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_GOT64_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "got64_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_GOT64_LO12, /* type (80). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_GOT64_LO12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_GOT64_LO12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "got64_lo12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_GOT64_LO20, /* type (81). */
+ 32, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_GOT64_LO20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_GOT64_LO20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "got64_lo20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_GOT64_HI12, /* type (82). */
+ 52, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_GOT64_HI12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_GOT64_HI12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "got64_hi12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20, /* type (83). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_LE_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_LE_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "le_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12, /* type (84). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_LE_LO12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_LE_LO12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "le_lo12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_LE64_LO20, /* type (85). */
+ 32, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_LE64_LO20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_LE64_LO20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "le64_lo20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_LE64_HI12, /* type (86). */
+ 52, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_LE64_HI12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_LE64_HI12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "le64_hi12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_HI20, /* type (87). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_IE_PC_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_IE_PC_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ie_pc_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_LO12, /* type (88). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_IE_PC_LO12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_IE_PC_LO12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ie_pc_lo12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_LO20, /* type (89). */
+ 32, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_IE64_PC_LO20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_IE64_PC_LO20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ie64_pc_lo20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_HI12, /* type (90). */
+ 52, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_IE64_PC_HI12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_IE64_PC_HI12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ie64_pc_hi12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_IE64_HI20, /* type (91). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_IE64_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_IE64_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ie64_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_IE64_LO12, /* type (92). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_IE64_LO12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_IE64_LO12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ie64_lo12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_IE64_LO20, /* type (93). */
+ 32, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_IE64_LO20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_IE64_LO20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ie64_lo20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_IE64_HI12, /* type (94). */
+ 52, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_IE64_HI12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_IE64_HI12, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ie64_hi12"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_LD_PC_HI20, /* type (95). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_LD_PC_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_LD_PC_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ld_pc_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_LD64_HI20, /* type (96). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_LD64_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_LD64_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "ld64_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_GD_PC_HI20, /* type (97). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_GD_PC_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_GD_PC_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "gd_pc_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_GD64_HI20, /* type (98). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_GD64_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0x1ffffe0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_TLS_GD64_HI20, /* bfd_reloc_code_real_type */
+ reloc_bits, /* adjust_reloc_bits */
+ "gd64_hi20"), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_RELAX, /* type (99). */
+ 0, /* rightshift */
+ 1, /* size */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_LARCH_RELAX", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_RELAX, /* bfd_reloc_code_real_type */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
+
};
reloc_howto_type *
@@ -697,8 +1357,6 @@ loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
if (loongarch_howto_table[r_type].howto.type == r_type)
return (reloc_howto_type *)&loongarch_howto_table[r_type];
- BFD_ASSERT (loongarch_howto_table[r_type].howto.type == r_type);
-
for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
if (loongarch_howto_table[i].howto.type == r_type)
return (reloc_howto_type *)&loongarch_howto_table[i];
@@ -734,6 +1392,17 @@ loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
{
BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
+ /* Fast search for new reloc types. */
+ if (BFD_RELOC_LARCH_B16 <= code && code < BFD_RELOC_LARCH_RELAX)
+ {
+ BFD_ASSERT (BFD_RELOC_LARCH_RELAX - BFD_RELOC_LARCH_B16
+ == R_LARCH_RELAX - R_LARCH_B16);
+ loongarch_reloc_howto_type *ht = NULL;
+ ht = &loongarch_howto_table[code - BFD_RELOC_LARCH_B16 + R_LARCH_B16];
+ BFD_ASSERT (ht->bfd_type == code);
+ return (reloc_howto_type *)ht;
+ }
+
for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
if (loongarch_howto_table[i].bfd_type == code)
return (reloc_howto_type *)&loongarch_howto_table[i];
@@ -745,56 +1414,89 @@ loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return NULL;
}
+bfd_reloc_code_real_type
+loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *l_r_name)
+{
+ for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
+ {
+ loongarch_reloc_howto_type *lht = &loongarch_howto_table[i];
+ if ((NULL != lht->larch_reloc_type_name)
+ && (0 == strcmp (lht->larch_reloc_type_name, l_r_name)))
+ return lht->bfd_type;
+ }
+
+ (*_bfd_error_handler) (_("%pB: unsupported relocation type name %s"),
+ abfd, l_r_name);
+ bfd_set_error (bfd_error_bad_value);
+ return BFD_RELOC_NONE;
+}
+
+
+/* Functions for reloc bits field.
+ 1. Signed extend *fix_val.
+ 2. Return false if overflow. */
+
#define LARCH_RELOC_BFD_VMA_BIT_MASK(bitsize) \
(~((((bfd_vma)0x1) << (bitsize)) - 1))
/* Adjust val to perform insn
- * BFD_RELOC_LARCH_SOP_POP_32_S_10_5
- * BFD_RELOC_LARCH_SOP_POP_32_S_10_12
- * BFD_RELOC_LARCH_SOP_POP_32_U_10_12
- * BFD_RELOC_LARCH_SOP_POP_32_S_10_16
- * BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2
- * BFD_RELOC_LARCH_SOP_POP_32_S_5_20
- * BFD_RELOC_LARCH_SOP_POP_32_U.
-*/
-
-bool loongarch_gen_adjust_reloc_bits (reloc_howto_type *howto, bfd_vma *fix_val)
+ BFD_RELOC_LARCH_SOP_POP_32_S_10_5
+ BFD_RELOC_LARCH_SOP_POP_32_S_10_12
+ BFD_RELOC_LARCH_SOP_POP_32_U_10_12
+ BFD_RELOC_LARCH_SOP_POP_32_S_10_16
+ BFD_RELOC_LARCH_SOP_POP_32_S_5_20
+ BFD_RELOC_LARCH_SOP_POP_32_U. */
+static bool
+reloc_bits (reloc_howto_type *howto, bfd_vma *fix_val)
{
- bfd_vma val = *fix_val;
- /* Check val low bits if rightshift != 0, before rightshift */
- if (howto->rightshift
- && (((0x1UL << howto->rightshift) - 1) & val))
+ bfd_signed_vma val = ((bfd_signed_vma)(*fix_val)) >> howto->rightshift;
+
+ /* Perform insn bits field. */
+ val = val & (((bfd_vma)0x1 << howto->bitsize) - 1);
+ val <<= howto->bitpos;
+
+ *fix_val = (bfd_vma)val;
+
+ return true;
+}
+
+/* Adjust val to perform insn
+ R_LARCH_SOP_POP_32_S_10_16_S2
+ R_LARCH_B16. */
+static bool
+reloc_bits_b16 (reloc_howto_type *howto, bfd_vma *fix_val)
+{
+ if (howto->complain_on_overflow != complain_overflow_signed)
+ return false;
+
+ bfd_signed_vma val = *fix_val;
+
+ /* Judge whether 4 bytes align. */
+ if (val & ((0x1UL << howto->rightshift) - 1))
return false;
int bitsize = howto->bitsize + howto->rightshift;
+ bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
- /* Return false if overflow. */
- if (howto->complain_on_overflow == complain_overflow_signed)
+ /* If val < 0, sign bit is 1. */
+ if (sig_bit)
{
- bfd_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
- /* If val < 0. */
- if (sig_bit)
- {
- if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
- != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1))
- return false;
- }
- else
- {
- if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
- return false;
- }
+ /* Signed bits is 1. */
+ if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
+ != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1))
+ return false;
}
- else if (howto->complain_on_overflow == complain_overflow_unsigned)
+ else
{
+ /* Signed bits is 0. */
if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val)
return false;
}
- else
- return false;
/* Perform insn bits field. */
- val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift;
+ val >>= howto->rightshift;
+ val = val & (((bfd_vma)0x1 << howto->bitsize) - 1);
val <<= howto->bitpos;
*fix_val = val;
@@ -802,22 +1504,24 @@ bool loongarch_gen_adjust_reloc_bits (reloc_howto_type *howto, bfd_vma *fix_val)
return true;
}
-/* Reloc type R_LARCH_SOP_POP_32_S_0_5_10_16_S2. */
-bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto,
- bfd_vma *fix_val)
+/* Reloc type :
+ R_LARCH_SOP_POP_32_S_0_5_10_16_S2
+ R_LARCH_B21. */
+static bool
+reloc_bits_b21 (reloc_howto_type *howto,
+ bfd_vma *fix_val)
{
- bfd_vma val = *fix_val;
- /* Check val low bits if rightshift != 0, before rightshift */
- if (howto->rightshift
- && (((0x1UL << howto->rightshift) - 1) & val))
+ if (howto->complain_on_overflow != complain_overflow_signed)
return false;
- /* Return false if overflow. */
- if (howto->complain_on_overflow != complain_overflow_signed)
+ bfd_signed_vma val = *fix_val;
+
+ if (val & ((0x1UL << howto->rightshift) - 1))
return false;
int bitsize = howto->bitsize + howto->rightshift;
- bfd_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
+ bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
+
/* If val < 0. */
if (sig_bit)
{
@@ -827,14 +1531,15 @@ bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto,
}
else
{
- if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
+ if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val)
return false;
}
/* Perform insn bits field. */
- val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift;
+ val >>= howto->rightshift;
+ val = val & (((bfd_vma)0x1 << howto->bitsize) - 1);
- /* Perform insn bits field. 20:16>>16, 15:0<<10 */
+ /* Perform insn bits field. 15:0<<10, 20:16>>16. */
val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f);
*fix_val = val;
@@ -842,22 +1547,25 @@ bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto,
return true;
}
-/* Reloc type R_LARCH_SOP_POP_32_S_0_10_10_16_S2. */
-bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto,
- bfd_vma *fix_val)
+/* Reloc type:
+ R_LARCH_SOP_POP_32_S_0_10_10_16_S2
+ R_LARCH_B26. */
+static bool
+reloc_bits_b26 (reloc_howto_type *howto,
+ bfd_vma *fix_val)
{
- bfd_vma val = *fix_val;
- /* Check val low bits if rightshift != 0, before rightshift */
- if (howto->rightshift
- && (((0x1UL << howto->rightshift) - 1) & val))
- return false;
-
/* Return false if overflow. */
if (howto->complain_on_overflow != complain_overflow_signed)
return false;
+ bfd_signed_vma val = *fix_val;
+
+ if (val & ((0x1UL << howto->rightshift) - 1))
+ return false;
+
int bitsize = howto->bitsize + howto->rightshift;
- bfd_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
+ bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
+
/* If val < 0. */
if (sig_bit)
{
@@ -867,14 +1575,15 @@ bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto,
}
else
{
- if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
+ if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val)
return false;
}
/* Perform insn bits field. */
- val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift;
+ val >>= howto->rightshift;
+ val = val & (((bfd_vma)0x1 << howto->bitsize) - 1);
- /* Perform insn bits field. 25:16>>16, 15:0<<10 */
+ /* Perform insn bits field. 25:16>>16, 15:0<<10. */
val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff);
*fix_val = val;
@@ -882,8 +1591,9 @@ bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto,
return true;
}
-bool loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto,
- bfd_vma *fix_val)
+bool
+loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto,
+ bfd_vma *fix_val)
{
BFD_ASSERT (((loongarch_reloc_howto_type *)howto)->adjust_reloc_bits);
return ((loongarch_reloc_howto_type *)
diff --git a/bfd/elfxx-loongarch.h b/bfd/elfxx-loongarch.h
index 8ea63d03fa5..7b8a72130f1 100644
--- a/bfd/elfxx-loongarch.h
+++ b/bfd/elfxx-loongarch.h
@@ -30,6 +30,10 @@ loongarch_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code);
extern reloc_howto_type *
loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name);
+extern bfd_reloc_code_real_type
+loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *l_r_name);
+
bool loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto, bfd_vma *fix_val);
/* TRUE if this is a PLT reference to a local IFUNC. */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 29e8187f95f..b23ae4b755c 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3457,6 +3457,42 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_LARCH_SUB24",
"BFD_RELOC_LARCH_SUB32",
"BFD_RELOC_LARCH_SUB64",
+ "BFD_RELOC_LARCH_B16",
+ "BFD_RELOC_LARCH_B21",
+ "BFD_RELOC_LARCH_B26",
+ "BFD_RELOC_LARCH_ABS_HI20",
+ "BFD_RELOC_LARCH_ABS_LO12",
+ "BFD_RELOC_LARCH_ABS64_LO20",
+ "BFD_RELOC_LARCH_ABS64_HI12",
+ "BFD_RELOC_LARCH_PCALA_HI20",
+ "BFD_RELOC_LARCH_PCALA_LO12",
+ "BFD_RELOC_LARCH_PCALA64_LO20",
+ "BFD_RELOC_LARCH_PCALA64_HI12",
+ "BFD_RELOC_LARCH_GOT_PC_HI20",
+ "BFD_RELOC_LARCH_GOT_PC_LO12",
+ "BFD_RELOC_LARCH_GOT64_PC_LO20",
+ "BFD_RELOC_LARCH_GOT64_PC_HI12",
+ "BFD_RELOC_LARCH_GOT64_HI20",
+ "BFD_RELOC_LARCH_GOT64_LO12",
+ "BFD_RELOC_LARCH_GOT64_LO20",
+ "BFD_RELOC_LARCH_GOT64_HI12",
+ "BFD_RELOC_LARCH_TLS_LE_HI20",
+ "BFD_RELOC_LARCH_TLS_LE_LO12",
+ "BFD_RELOC_LARCH_TLS_LE64_LO20",
+ "BFD_RELOC_LARCH_TLS_LE64_HI12",
+ "BFD_RELOC_LARCH_TLS_IE_PC_HI20",
+ "BFD_RELOC_LARCH_TLS_IE_PC_LO12",
+ "BFD_RELOC_LARCH_TLS_IE64_PC_LO20",
+ "BFD_RELOC_LARCH_TLS_IE64_PC_HI12",
+ "BFD_RELOC_LARCH_TLS_IE64_HI20",
+ "BFD_RELOC_LARCH_TLS_IE64_LO12",
+ "BFD_RELOC_LARCH_TLS_IE64_LO20",
+ "BFD_RELOC_LARCH_TLS_IE64_HI12",
+ "BFD_RELOC_LARCH_TLS_LD_PC_HI20",
+ "BFD_RELOC_LARCH_TLS_LD64_HI20",
+ "BFD_RELOC_LARCH_TLS_GD_PC_HI20",
+ "BFD_RELOC_LARCH_TLS_GD64_HI20",
+ "BFD_RELOC_LARCH_RELAX",
"@@overflow: BFD_RELOC_UNUSED@@",
};
#endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 36999fe9a40..836fa162108 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8228,6 +8228,85 @@ ENUMX
BFD_RELOC_LARCH_SUB32
ENUMX
BFD_RELOC_LARCH_SUB64
+
+ENUMX
+ BFD_RELOC_LARCH_B16
+ENUMX
+ BFD_RELOC_LARCH_B21
+ENUMX
+ BFD_RELOC_LARCH_B26
+
+ENUMX
+ BFD_RELOC_LARCH_ABS_HI20
+ENUMX
+ BFD_RELOC_LARCH_ABS_LO12
+ENUMX
+ BFD_RELOC_LARCH_ABS64_LO20
+ENUMX
+ BFD_RELOC_LARCH_ABS64_HI12
+
+ENUMX
+ BFD_RELOC_LARCH_PCALA_HI20
+ENUMX
+ BFD_RELOC_LARCH_PCALA_LO12
+ENUMX
+ BFD_RELOC_LARCH_PCALA64_LO20
+ENUMX
+ BFD_RELOC_LARCH_PCALA64_HI12
+
+ENUMX
+ BFD_RELOC_LARCH_GOT_PC_HI20
+ENUMX
+ BFD_RELOC_LARCH_GOT_PC_LO12
+ENUMX
+ BFD_RELOC_LARCH_GOT64_PC_LO20
+ENUMX
+ BFD_RELOC_LARCH_GOT64_PC_HI12
+ENUMX
+ BFD_RELOC_LARCH_GOT64_HI20
+ENUMX
+ BFD_RELOC_LARCH_GOT64_LO12
+ENUMX
+ BFD_RELOC_LARCH_GOT64_LO20
+ENUMX
+ BFD_RELOC_LARCH_GOT64_HI12
+
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE_HI20
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE_LO12
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE64_LO20
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE64_HI12
+ENUMX
+ BFD_RELOC_LARCH_TLS_IE_PC_HI20
+ENUMX
+ BFD_RELOC_LARCH_TLS_IE_PC_LO12
+ENUMX
+ BFD_RELOC_LARCH_TLS_IE64_PC_LO20
+ENUMX
+ BFD_RELOC_LARCH_TLS_IE64_PC_HI12
+ENUMX
+ BFD_RELOC_LARCH_TLS_IE64_HI20
+ENUMX
+ BFD_RELOC_LARCH_TLS_IE64_LO12
+ENUMX
+ BFD_RELOC_LARCH_TLS_IE64_LO20
+ENUMX
+ BFD_RELOC_LARCH_TLS_IE64_HI12
+ENUMX
+ BFD_RELOC_LARCH_TLS_LD_PC_HI20
+ENUMX
+ BFD_RELOC_LARCH_TLS_LD64_HI20
+ENUMX
+ BFD_RELOC_LARCH_TLS_GD_PC_HI20
+ENUMX
+ BFD_RELOC_LARCH_TLS_GD64_HI20
+
+ENUMX
+ BFD_RELOC_LARCH_RELAX
+
ENUMDOC
LARCH relocations.
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index b7aa4ff069c..863dad3a371 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -90,6 +90,142 @@ RELOC_NUMBER (R_LARCH_SUB64, 56)
RELOC_NUMBER (R_LARCH_GNU_VTINHERIT, 57)
RELOC_NUMBER (R_LARCH_GNU_VTENTRY, 58)
+
+/* B16:
+ beq/bne/blt/bge/bltu/bgeu/jirl
+ %b16 (sym). */
+RELOC_NUMBER (R_LARCH_B16, 64)
+/* B21:
+ beqz/bnez
+ %b16 (sym). */
+RELOC_NUMBER (R_LARCH_B21, 65)
+/* B26:
+ b/bl
+ %b26 (sym) or %plt (sym). */
+RELOC_NUMBER (R_LARCH_B26, 66)
+
+/* ABS: 32/64
+ lu12i.w
+ %abs_hi20 (sym). */
+RELOC_NUMBER (R_LARCH_ABS_HI20, 67)
+/* ABS: 32/64
+ ori
+ %abs_lo12 (sym). */
+RELOC_NUMBER (R_LARCH_ABS_LO12, 68)
+
+/* ABS: 64
+ lu32i.d
+ %abs64_lo20 (sym). */
+RELOC_NUMBER (R_LARCH_ABS64_LO20, 69)
+/* ABS: 64
+ lu52i.d
+ %abs64_hi12 (sym). */
+RELOC_NUMBER (R_LARCH_ABS64_HI12, 70)
+
+/* PCREL: 32/64
+ pcalau12i
+ %pc_hi20 (sym). */
+RELOC_NUMBER (R_LARCH_PCALA_HI20, 71)
+/* PCREL: 32/64
+ addi.w/addi.d
+ %pc_lo12 (sym). */
+RELOC_NUMBER (R_LARCH_PCALA_LO12, 72)
+/* PCREL: 64
+ lu32i.d
+ %pc64_lo20 (sym). */
+RELOC_NUMBER (R_LARCH_PCALA64_LO20, 73)
+/* PCREL: 64
+ lu52i.d
+ %pc64_hi12 (sym). */
+RELOC_NUMBER (R_LARCH_PCALA64_HI12, 74)
+
+/* GOT: 32/64
+ pcalau12i
+ %got_pc_hi20 (got). */
+RELOC_NUMBER (R_LARCH_GOT_PC_HI20, 75)
+/* GOT: 32/64
+ ld.w/ld.d
+ %got_pc_lo12 (got). */
+RELOC_NUMBER (R_LARCH_GOT_PC_LO12, 76)
+/* GOT: 32/64
+ lu32i.d
+ %got_pc_lo12 (got). */
+RELOC_NUMBER (R_LARCH_GOT64_PC_LO20, 77)
+/* GOT64: PCREL
+ lu52i.d
+ %got64_pc_hi12 (got). */
+RELOC_NUMBER (R_LARCH_GOT64_PC_HI12, 78)
+/* GOT64: ABS
+ lu12i.w
+ %got64_hi20 (got). */
+RELOC_NUMBER (R_LARCH_GOT64_HI20, 79)
+/* GOT64: ABS
+ ori
+ %got64_lo12 (got). */
+RELOC_NUMBER (R_LARCH_GOT64_LO12, 80)
+/* GOT64: ABS
+ lu32i.d
+ %got64_lo20 (got). */
+RELOC_NUMBER (R_LARCH_GOT64_LO20, 81)
+/* GOT64: ABS
+ lu52i.d
+ %got64_hi12 (got). */
+RELOC_NUMBER (R_LARCH_GOT64_HI12, 82)
+
+/* TLS-LE: 32/64
+ lu12i.w
+ %le_hi20 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_HI20, 83)
+/* TLS-LE: 32/64
+ ori
+ %le_lo12 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_LO12, 84)
+/* TLS-LE: 64
+ lu32i.d
+ %le64_lo20 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE64_LO20, 85)
+/* TLS-LE: 64
+ lu52i.d
+ %le64_hi12 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE64_HI12, 86)
+
+/* TLS-IE: 32/64
+ pcalau12i
+ %ie_pc_hi20 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_IE_PC_HI20, 87)
+RELOC_NUMBER (R_LARCH_TLS_IE_PC_LO12, 88)
+RELOC_NUMBER (R_LARCH_TLS_IE64_PC_LO20, 89)
+RELOC_NUMBER (R_LARCH_TLS_IE64_PC_HI12, 90)
+
+/* TLS-IE64: ABS
+ lu12i.w
+ %ie64_hi20 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_IE64_HI20, 91)
+RELOC_NUMBER (R_LARCH_TLS_IE64_LO12, 92)
+RELOC_NUMBER (R_LARCH_TLS_IE64_LO20, 93)
+RELOC_NUMBER (R_LARCH_TLS_IE64_HI12, 94)
+
+/* TLS-LD: 32/64
+ pcalau12i
+ %ld_pc_hi20 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LD_PC_HI20, 95)
+/* TLS-LD64: ABS
+ lu12i.w
+ %ld64_hi20 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LD64_HI20, 96)
+
+/* TLS-GD: 32/64
+ pcalau12i
+ %gd_pc_hi20 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_GD_PC_HI20, 97)
+/* TLS-GD64: ABS
+ lu12i.w
+ %gd64_hi20 (sym). */
+RELOC_NUMBER (R_LARCH_TLS_GD64_HI20, 98)
+
+/* RELAX. */
+RELOC_NUMBER (R_LARCH_RELAX, 99)
+
END_RELOC_NUMBERS (R_LARCH_count)
/* Processor specific flags for the ELF header e_flags field. */
@@ -102,9 +238,9 @@ END_RELOC_NUMBERS (R_LARCH_count)
#define EF_LOONGARCH_ABI_ILP32_SINGLE_FLOAT 0x6
#define EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT 0x7
-#define EF_LOONGARCH_ABI_MASK 0x7
-#define EF_LOONGARCH_ABI_ILP32_MASK 0x4
-#define EF_LOONGARCH_ABI_FLOAT_MASK 0x3
+#define EF_LOONGARCH_ABI_MASK 0x7
+#define EF_LOONGARCH_ABI_ILP32_MASK 0x4
+#define EF_LOONGARCH_ABI_FLOAT_MASK 0x3
#define EF_LOONGARCH_ABI_SOFT_FLOAT_MASK 0x1
#define EF_LOONGARCH_ABI_SINGLE_FLOAT_MASK 0x2
#define EF_LOONGARCH_ABI_DOUBLE_FLOAT_MASK 0x3
--
2.31.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 2/5 v1] LoongArch:opcodes: Add new reloc types.
2022-07-18 8:43 [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types liuzhensong
@ 2022-07-18 8:43 ` liuzhensong
2022-07-18 8:43 ` [PATCH 3/5 v1] LoongArch: gas: " liuzhensong
` (4 subsequent siblings)
5 siblings, 0 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-18 8:43 UTC (permalink / raw)
To: binutils; +Cc: xuchenghua, mengqinggang, liuzhensong
opcodes: Replace old insns with news and generate new relocate types
while macro insns expanding.
opcodes/
loongarch-opc.c
---
opcodes/loongarch-opc.c | 387 ++++++++++++++++++++++------------------
1 file changed, 217 insertions(+), 170 deletions(-)
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 62a2edb1ca9..1c7dd2e8ee9 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -103,158 +103,205 @@ const char *const loongarch_x_normal_name[32] =
"$xr24", "$xr25", "$xr26", "$xr27", "$xr28", "$xr29", "$xr30", "$xr31",
};
+/* Can not use xx_pa for abs. */
+
+/* For LoongArch32 abs. */
+#define INSN_LA_ABS32 \
+ "lu12i.w %1,%%abs_hi20(%2);" \
+ "ori %1,%1,%%abs_lo12(%2);", \
+ &LARCH_opts.ase_ilp32, \
+ &LARCH_opts.ase_lp64
+#define INSN_LA_ABS64 \
+ "lu12i.w %1,%%abs_hi20(%2);" \
+ "ori %1,%1,%%abs_lo12(%2);" \
+ "lu32i.d %1,%%abs64_lo20(%2);" \
+ "lu52i.d %1,%1,%%abs64_hi12(%2);", \
+ &LARCH_opts.ase_lp64, 0
+
+#define INSN_LA_PCREL32 \
+ "pcalau12i %1,%%pc_hi20(%2);" \
+ "addi.w %1,%1,%%pc_lo12(%2);", \
+ &LARCH_opts.ase_ilp32, \
+ &LARCH_opts.ase_lp64
+#define INSN_LA_PCREL64 \
+ "pcalau12i %1,%%pc_hi20(%2);" \
+ "addi.d %1,%1,%%pc_lo12(%2);", \
+ &LARCH_opts.ase_lp64, 0
+#define INSN_LA_PCREL64_LARGE \
+ "pcalau12i %1,%%pc_hi20(%3);" \
+ "addi.d %2,$r0,%%pc_lo12(%3);" \
+ "lu32i.d %2,%%pc64_lo20(%3);" \
+ "lu52i.d %2,%2,%%pc64_hi12(%3);" \
+ "add.d %1,%1,%2;", \
+ &LARCH_opts.ase_lp64, 0
+
+#define INSN_LA_GOT32 \
+ "pcalau12i %1,%%got_pc_hi20(%2);" \
+ "ld.w %1,%1,%%got_pc_lo12(%2);", \
+ &LARCH_opts.ase_ilp32, \
+ &LARCH_opts.ase_lp64
+#define INSN_LA_GOT64 \
+ "pcalau12i %1,%%got_pc_hi20(%2);" \
+ "ld.d %1,%1,%%got_pc_lo12(%2);", \
+ &LARCH_opts.ase_lp64, 0
+/* got64 abs. */
+#define INSN_LA_GOT64_LARGE_ABS \
+ "lu12i.w %1,%%got64_hi20(%2);" \
+ "ori %1,%1,%%got64_lo12(%2);" \
+ "lu32i.d %1,%%got64_lo20(%2);" \
+ "lu52i.d %1,%1,%%got64_hi12(%2);" \
+ "ld.d %1,%1,0", \
+ &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gpcr
+/* got64 pic. */
+#define INSN_LA_GOT64_LARGE_PCREL \
+ "pcalau12i %1,%%got_pc_hi20(%3);" \
+ "addi.d %2,$r0,%%got_pc_lo12(%3);" \
+ "lu32i.d %2,%%got64_pc_lo20(%3);" \
+ "lu52i.d %2,%2,%%got64_pc_hi12(%3);"\
+ "ldx.d %1,%1,%2;", \
+ &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gabs
+
+/* For LoongArch32/64 cmode=normal. */
+#define INSN_LA_TLS_LE \
+ "lu12i.w %1,%%le_hi20(%2);" \
+ "ori %1,%1,%%le_lo12(%2);", \
+ &LARCH_opts.ase_ilp32, 0
+
+/* For LoongArch64 cmode=large. */
+#define INSN_LA_TLS_LE64_LARGE \
+ "lu12i.w %1,%%le_hi20(%2);" \
+ "ori %1,%1,%%le_lo12(%2);" \
+ "lu32i.d %1,%%le64_lo20(%2);" \
+ "lu52i.d %1,%1,%%le64_hi12(%2);", \
+ &LARCH_opts.ase_lp64, 0
+
+#define INSN_LA_TLS_IE32 \
+ "pcalau12i %1,%%ie_pc_hi20(%2);" \
+ "ld.w %1,%1,%%ie_pc_lo12(%2);", \
+ &LARCH_opts.ase_ilp32, \
+ &LARCH_opts.ase_lp64
+
+#define INSN_LA_TLS_IE64 \
+ "pcalau12i %1,%%ie_pc_hi20(%2);" \
+ "ld.d %1,%1,%%ie_pc_lo12(%2);", \
+ &LARCH_opts.ase_lp64, 0
+
+/* For ie64 pic. */
+#define INSN_LA_TLS_IE64_LARGE_PCREL \
+ "pcalau12i %1,%%ie_pc_hi20(%3);" \
+ "addi.d %2,$r0,%%ie_pc_lo12(%3);" \
+ "lu32i.d %2,%%ie64_pc_lo20(%3);" \
+ "lu52i.d %2,%2,%%ie64_pc_hi12(%3);"\
+ "ldx.d %1,%1,%2;", \
+ &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gabs
+
+/* For ie64 abs. */
+#define INSN_LA_TLS_IE64_LARGE_ABS \
+ "lu12i.w %1,%%ie64_hi20(%2);" \
+ "ori %1,%1,%%ie64_lo12(%2);" \
+ "lu32i.d %1,%%ie64_lo20(%2);" \
+ "lu52i.d %1,%1,%%ie64_hi12(%2);" \
+ "ld.d %1,%1,0", \
+ &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gpcr
+
+/* For LoongArch32/64 cmode=normal. */
+#define INSN_LA_TLS_LD32 \
+ "pcalau12i %1,%%ld_pc_hi20(%2);" \
+ "addi.w %1,%1,%%got_pc_lo12(%2);", \
+ &LARCH_opts.ase_ilp32, \
+ &LARCH_opts.ase_lp64
+#define INSN_LA_TLS_LD64 \
+ "pcalau12i %1,%%ld_pc_hi20(%2);" \
+ "addi.d %1,%1,%%got_pc_lo12(%2);", \
+ &LARCH_opts.ase_lp64, 0
+#define INSN_LA_TLS_LD64_LARGE_PCREL \
+ "pcalau12i %1,%%ld_pc_hi20(%3);" \
+ "addi.d %2,$r0,%%got_pc_lo12(%3);" \
+ "lu32i.d %2,%%got64_pc_lo20(%3);" \
+ "lu52i.d %2,%2,%%got64_pc_hi12(%3);"\
+ "add.d %1,%1,%2;", \
+ &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gabs
+#define INSN_LA_TLS_LD64_LARGE_ABS \
+ "lu12i.w %1,%%ld64_hi20(%2);" \
+ "ori %1,%1,%%got64_lo12(%2);" \
+ "lu32i.d %1,%%got64_lo20(%2);" \
+ "lu52i.d %1,%1,%%got64_hi12(%2);", \
+ &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gpcr
+
+#define INSN_LA_TLS_GD32 \
+ "pcalau12i %1,%%gd_pc_hi20(%2);" \
+ "addi.w %1,%1,%%got_pc_lo12(%2);", \
+ &LARCH_opts.ase_ilp32, \
+ &LARCH_opts.ase_lp64
+#define INSN_LA_TLS_GD64 \
+ "pcalau12i %1,%%gd_pc_hi20(%2);" \
+ "addi.d %1,%1,%%got_pc_lo12(%2);", \
+ &LARCH_opts.ase_lp64, 0
+#define INSN_LA_TLS_GD64_LARGE_PCREL \
+ "pcalau12i %1,%%gd_pc_hi20(%3);" \
+ "addi.d %2,$r0,%%got_pc_lo12(%3);" \
+ "lu32i.d %2,%%got64_pc_lo20(%3);" \
+ "lu52i.d %2,%2,%%got64_pc_hi12(%3);"\
+ "add.d %1,%1,%2;", \
+ &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gabs
+#define INSN_LA_TLS_GD64_LARGE_ABS \
+ "lu12i.w %1,%%gd64_hi20(%2);" \
+ "ori %1,%1,%%got64_lo12(%2);" \
+ "lu32i.d %1,%%got64_lo20(%2);" \
+ "lu52i.d %1,%1,%%got64_hi12(%2);", \
+ &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gpcr
+
+
static struct loongarch_opcode loongarch_macro_opcodes[] =
{
- /* match, mask, name, format, macro, include, exclude, pinfo. */
- { 0, 0, "li.w", "r,sc", "%f", 0, 0, 0},
- { 0, 0, "li.d", "r,sc", "%f", 0, 0, 0},
- { 0, 0, "la", "r,la", "la.global %1,%2", 0, 0, 0 },
-
- { 0, 0, "la.global", "r,la", "la.pcrel %1,%2",
- &LARCH_opts.ase_gpcr, 0, 0 },
- { 0, 0, "la.global", "r,r,la", "la.pcrel %1,%2,%3",
- &LARCH_opts.ase_gpcr, 0, 0 },
- { 0, 0, "la.global", "r,la", "la.abs %1,%2",
- &LARCH_opts.ase_gabs, 0, 0 },
- { 0, 0, "la.global", "r,r,la", "la.abs %1,%3",
- &LARCH_opts.ase_gabs, 0, 0 },
- { 0, 0, "la.global", "r,l", "la.got %1,%2", 0, 0, 0 },
- { 0, 0, "la.global", "r,r,l", "la.got %1,%2,%3", 0, 0, 0 },
-
- { 0, 0, "la.local", "r,la", "la.abs %1,%2",
- &LARCH_opts.ase_labs, 0, 0 },
- { 0, 0, "la.local", "r,r,la", "la.abs %1,%3",
- &LARCH_opts.ase_labs, 0, 0 },
- { 0, 0, "la.local", "r,la", "la.pcrel %1,%2", 0, 0, 0 },
- { 0, 0, "la.local", "r,r,la", "la.pcrel %1,%2,%3", 0, 0, 0 },
-
- { 0, 0, "la.abs", "r,la",
- "lu12i.w %1,%%abs(%2)>>12;"
- "ori %1,%1,%%abs(%2)&0xfff;",
- &LARCH_opts.ase_ilp32, &LARCH_opts.ase_lp64, 0 },
- { 0, 0, "la.abs", "r,la",
- "lu12i.w %1,%%abs(%2)<<32>>44;"
- "ori %1,%1,%%abs(%2)&0xfff;"
- "lu32i.d %1,%%abs(%2)<<12>>44;"
- "lu52i.d %1,%1,%%abs(%2)>>52;",
- &LARCH_opts.ase_lp64, 0, 0 },
-
- { 0, 0, "la.pcrel", "r,la",
- "pcaddu12i %1,%%pcrel(%2+0x800)<<32>>44;"
- "addi.w %1,%1,%%pcrel(%2+4)-(%%pcrel(%2+4+0x800)>>12<<12);",
- &LARCH_opts.ase_ilp32, &LARCH_opts.ase_lp64, 0 },
-
- { 0, 0, "la.pcrel", "r,la",
- "pcaddu12i %1,%%pcrel(%2+0x800)>>12;"
- "addi.d %1,%1,%%pcrel(%2+4)-(%%pcrel(%2+4+0x800)>>12<<12);",
- &LARCH_opts.ase_lp64, 0, 0 },
- { 0, 0, "la.pcrel", "r,r,la",
- "pcaddu12i %1,(%%pcrel(%3)-(%%pcrel(%3+0x80000000)>>32<<32))<<32>>44;"
- "ori %2,$r0,(%%pcrel(%3+4)-(%%pcrel(%3+4+0x80000000)>>32<<32))&0xfff;"
- "lu32i.d %2,%%pcrel(%3+8+0x80000000)<<12>>44;"
- "lu52i.d %2,%2,%%pcrel(%3+12+0x80000000)>>52;"
- "add.d %1,%1,%2;",
- &LARCH_opts.ase_lp64, 0, 0 },
-
- { 0, 0, "la.got", "r,l",
- "pcaddu12i %1,(%%pcrel(_GLOBAL_OFFSET_TABLE_+0x800)+%%gprel(%2))<<32>>44;"
- "ld.w "
- "%1,%1,%%pcrel(_GLOBAL_OFFSET_TABLE_+4)+%%gprel(%2)-((%%pcrel(_GLOBAL_"
- "OFFSET_TABLE_+4+0x800)+%%gprel(%2))>>12<<12);",
- &LARCH_opts.ase_ilp32, &LARCH_opts.ase_lp64, 0 },
-
- { 0, 0, "la.got", "r,l",
- "pcaddu12i %1,(%%pcrel(_GLOBAL_OFFSET_TABLE_+0x800)+%%gprel(%2))>>12;"
- "ld.d "
- "%1,%1,%%pcrel(_GLOBAL_OFFSET_TABLE_+4)+%%gprel(%2)-((%%pcrel(_GLOBAL_"
- "OFFSET_TABLE_+4+0x800)+%%gprel(%2))>>12<<12);",
- &LARCH_opts.ase_lp64, 0, 0 },
- { 0, 0, "la.got", "r,r,l",
- "pcaddu12i "
- "%1,(%%pcrel(_GLOBAL_OFFSET_TABLE_)+%%gprel(%3)-((%%pcrel(_GLOBAL_OFFSET_"
- "TABLE_+0x80000000)+%%gprel(%3))>>32<<32))<<32>>44;"
- "ori "
- "%2,$r0,(%%pcrel(_GLOBAL_OFFSET_TABLE_+4)+%%gprel(%3)-((%%pcrel(_GLOBAL_"
- "OFFSET_TABLE_+4+0x80000000)+%%gprel(%3))>>32<<32))&0xfff;"
- "lu32i.d "
- "%2,(%%pcrel(_GLOBAL_OFFSET_TABLE_+8+0x80000000)+%%gprel(%3))<<12>>44;"
- "lu52i.d "
- "%2,%2,(%%pcrel(_GLOBAL_OFFSET_TABLE_+12+0x80000000)+%%gprel(%3))>>52;"
- "ldx.d %1,%1,%2;",
- &LARCH_opts.ase_lp64, 0, 0 },
-
- { 0, 0, "la.tls.le", "r,la",
- "lu12i.w %1,%%tprel(%2)>>12;"
- "ori %1,%1,%%tprel(%2)&0xfff",
- &LARCH_opts.ase_ilp32, &LARCH_opts.ase_lp64, 0 },
- /* { 0, 0, "la.tls.le", "r,la",
- * "lu12i.w %1,%%tprel(%2)>>12;"
- * "ori %1,%1,%%tprel(%2)&0xfff"
- * , &LARCH_opts.addrwidth_is_64, 0, 0}, */
- { 0, 0, "la.tls.le", "r,la",
- "lu12i.w %1,%%tprel(%2)<<32>>44;"
- "ori %1,%1,%%tprel(%2)&0xfff;"
- "lu32i.d %1,%%tprel(%2)<<12>>44;"
- "lu52i.d %1,%1,%%tprel(%2)>>52;",
- &LARCH_opts.ase_lp64, 0, 0 },
-
- { 0, 0, "la.tls.ie", "r,l",
- "pcaddu12i %1,(%%pcrel(_GLOBAL_OFFSET_TABLE_+0x800)+%%tlsgot(%2))<<32>>44;"
- "ld.w "
- "%1,%1,%%pcrel(_GLOBAL_OFFSET_TABLE_+4)+%%tlsgot(%2)-((%%pcrel(_GLOBAL_"
- "OFFSET_TABLE_+4+0x800)+%%tlsgot(%2))>>12<<12);",
- &LARCH_opts.ase_ilp32, &LARCH_opts.ase_lp64, 0 },
-
- { 0, 0, "la.tls.ie", "r,l",
- "pcaddu12i %1,(%%pcrel(_GLOBAL_OFFSET_TABLE_+0x800)+%%tlsgot(%2))>>12;"
- "ld.d "
- "%1,%1,%%pcrel(_GLOBAL_OFFSET_TABLE_+4)+%%tlsgot(%2)-((%%pcrel(_GLOBAL_"
- "OFFSET_TABLE_+4+0x800)+%%tlsgot(%2))>>12<<12);",
- &LARCH_opts.ase_lp64, 0, 0 },
- { 0, 0, "la.tls.ie", "r,r,l",
- "pcaddu12i "
- "%1,(%%pcrel(_GLOBAL_OFFSET_TABLE_)+%%tlsgot(%3)-((%%pcrel(_GLOBAL_OFFSET_"
- "TABLE_+0x80000000)+%%tlsgot(%3))>>32<<32))<<32>>44;"
- "ori "
- "%2,$r0,(%%pcrel(_GLOBAL_OFFSET_TABLE_+4)+%%tlsgot(%3)-((%%pcrel(_GLOBAL_"
- "OFFSET_TABLE_+4+0x80000000)+%%tlsgot(%3))>>32<<32))&0xfff;"
- "lu32i.d "
- "%2,(%%pcrel(_GLOBAL_OFFSET_TABLE_+8+0x80000000)+%%tlsgot(%3))<<12>>44;"
- "lu52i.d "
- "%2,%2,(%%pcrel(_GLOBAL_OFFSET_TABLE_+12+0x80000000)+%%tlsgot(%3))>>52;"
- "ldx.d %1,%1,%2;",
- &LARCH_opts.ase_lp64, 0, 0 },
-
- { 0, 0, "la.tls.ld", "r,l", "la.tls.gd %1,%2", 0, 0, 0 },
- { 0, 0, "la.tls.ld", "r,r,l", "la.tls.gd %1,%2,%3",
- &LARCH_opts.ase_lp64, 0, 0 },
-
- { 0, 0, "la.tls.gd", "r,l",
- "pcaddu12i %1,(%%pcrel(_GLOBAL_OFFSET_TABLE_+0x800)+%%tlsgd(%2))<<32>>44;"
- "addi.w "
- "%1,%1,%%pcrel(_GLOBAL_OFFSET_TABLE_+4)+%%tlsgd(%2)-((%%pcrel(_GLOBAL_"
- "OFFSET_TABLE_+4+0x800)+%%tlsgd(%2))>>12<<12);",
- &LARCH_opts.ase_ilp32, &LARCH_opts.ase_lp64, 0 },
-
- { 0, 0, "la.tls.gd", "r,l",
- "pcaddu12i %1,(%%pcrel(_GLOBAL_OFFSET_TABLE_+0x800)+%%tlsgd(%2))>>12;"
- "addi.d "
- "%1,%1,%%pcrel(_GLOBAL_OFFSET_TABLE_+4)+%%tlsgd(%2)-((%%pcrel(_GLOBAL_"
- "OFFSET_TABLE_+4+0x800)+%%tlsgd(%2))>>12<<12);",
- &LARCH_opts.ase_lp64, 0, 0 },
- { 0, 0, "la.tls.gd", "r,r,l",
- "pcaddu12i "
- "%1,(%%pcrel(_GLOBAL_OFFSET_TABLE_)+%%tlsgd(%3)-((%%pcrel(_GLOBAL_OFFSET_"
- "TABLE_+0x80000000)+%%tlsgd(%3))>>32<<32))<<32>>44;"
- "ori "
- "%2,$r0,(%%pcrel(_GLOBAL_OFFSET_TABLE_+4)+%%tlsgd(%3)-((%%pcrel(_GLOBAL_"
- "OFFSET_TABLE_+4+0x80000000)+%%tlsgd(%3))>>32<<32))&0xfff;"
- "lu32i.d "
- "%2,(%%pcrel(_GLOBAL_OFFSET_TABLE_+8+0x80000000)+%%tlsgd(%3))<<12>>44;"
- "lu52i.d "
- "%2,%2,(%%pcrel(_GLOBAL_OFFSET_TABLE_+12+0x80000000)+%%tlsgd(%3))>>52;"
- "add.d %1,%1,%2;",
- &LARCH_opts.ase_lp64, 0, 0 },
+ /* match, mask, name, format, macro, include, exclude, pinfo. */
+ { 0, 0, "li.w", "r,sc", "%f", 0, 0, 0 },
+ { 0, 0, "li.d", "r,sc", "%f", 0, 0, 0 },
+
+ { 0, 0, "la", "r,la", "la.global %1,%2", 0, 0, 0 },
+ { 0, 0, "la.global", "r,la", "la.pcrel %1,%2", &LARCH_opts.ase_gpcr, 0, 0 },
+ { 0, 0, "la.global", "r,r,la", "la.pcrel %1,%2,%3", &LARCH_opts.ase_gpcr, 0, 0 },
+ { 0, 0, "la.global", "r,la", "la.abs %1,%2", &LARCH_opts.ase_gabs, 0, 0 },
+ { 0, 0, "la.global", "r,r,la", "la.abs %1,%3", &LARCH_opts.ase_gabs, 0, 0 },
+ { 0, 0, "la.global", "r,la", "la.got %1,%2", 0, 0, 0 },
+ { 0, 0, "la.global", "r,r,la", "la.got %1,%2,%3", &LARCH_opts.ase_lp64, 0, 0 },
+
+ { 0, 0, "la.local", "r,la", "la.abs %1,%2", &LARCH_opts.ase_labs, 0, 0 },
+ { 0, 0, "la.local", "r,r,la", "la.abs %1,%3", &LARCH_opts.ase_labs, 0, 0 },
+ { 0, 0, "la.local", "r,la", "la.pcrel %1,%2", 0, 0, 0 },
+ { 0, 0, "la.local", "r,r,la", "la.pcrel %1,%2,%3", &LARCH_opts.ase_lp64, 0, 0 },
+
+ { 0, 0, "la.abs", "r,la", INSN_LA_ABS32, 0 },
+ { 0, 0, "la.abs", "r,la", INSN_LA_ABS64, 0 },
+ { 0, 0, "la.pcrel", "r,la", INSN_LA_PCREL32, 0 },
+ { 0, 0, "la.pcrel", "r,la", INSN_LA_PCREL64, 0 },
+ { 0, 0, "la.pcrel", "r,r,la", INSN_LA_PCREL64_LARGE, 0 },
+ { 0, 0, "la.got", "r,la", INSN_LA_GOT32, 0 },
+ { 0, 0, "la.got", "r,la", INSN_LA_GOT64, 0 },
+ { 0, 0, "la.got", "r,la", INSN_LA_GOT64_LARGE_ABS, 0 },
+ { 0, 0, "la.got", "r,r,la", INSN_LA_GOT64_LARGE_PCREL, 0 },
+ { 0, 0, "la.tls.le", "r,l", INSN_LA_TLS_LE, 0 },
+ { 0, 0, "la.tls.le", "r,l", INSN_LA_TLS_LE64_LARGE, 0 },
+ { 0, 0, "la.tls.ie", "r,l", INSN_LA_TLS_IE32, 0 },
+ { 0, 0, "la.tls.ie", "r,l", INSN_LA_TLS_IE64, 0 },
+ { 0, 0, "la.tls.ie", "r,l", INSN_LA_TLS_IE64_LARGE_ABS, 0 },
+ { 0, 0, "la.tls.ie", "r,r,l", INSN_LA_TLS_IE64_LARGE_PCREL, 0 },
+ { 0, 0, "la.tls.ld", "r,l", INSN_LA_TLS_LD32, 0 },
+ { 0, 0, "la.tls.ld", "r,l", INSN_LA_TLS_LD64, 0 },
+ { 0, 0, "la.tls.ld", "r,l", INSN_LA_TLS_LD64_LARGE_ABS, 0 },
+ { 0, 0, "la.tls.ld", "r,r,l", INSN_LA_TLS_LD64_LARGE_PCREL, 0 },
+ { 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD32, 0 },
+ { 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64, 0 },
+ { 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64_LARGE_ABS, 0 },
+ { 0, 0, "la.tls.gd", "r,r,l", INSN_LA_TLS_GD64_LARGE_PCREL, 0 },
{ 0 } /* Terminate the list. */
};
@@ -728,9 +775,9 @@ static struct loongarch_opcode loongarch_double_float_load_store_opcodes[] =
static struct loongarch_opcode loongarch_float_jmp_opcodes[] =
{
- { 0x0, 0x0, "bceqz", "c,la", "bceqz %1,%%pcrel(%2)", 0, 0, 0 },
+ { 0x0, 0x0, "bceqz", "c,la", "bceqz %1,%%b21(%2)", 0, 0, 0 },
{ 0x48000000, 0xfc000300, "bceqz", "c5:3,sb0:5|10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bcnez", "c,la", "bcnez %1,%%pcrel(%2)", 0, 0, 0 },
+ { 0x0, 0x0, "bcnez", "c,la", "bcnez %1,%%b21(%2)", 0, 0, 0 },
{ 0x48000100, 0xfc000300, "bcnez", "c5:3,sb0:5|10:16<<2", 0, 0, 0, 0 },
{ 0 } /* Terminate the list. */
};
@@ -738,43 +785,43 @@ static struct loongarch_opcode loongarch_float_jmp_opcodes[] =
static struct loongarch_opcode loongarch_jmp_opcodes[] =
{
/* match, mask, name, format, macro, include, exclude, pinfo. */
- { 0x0, 0x0, "bltz", "r,la", "bltz %1,%%pcrel(%2)", 0, 0, 0 },
+ { 0x0, 0x0, "bltz", "r,la", "bltz %1,%%b16(%2)", 0, 0, 0 },
{ 0x60000000, 0xfc00001f, "bltz", "r5:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bgtz", "r,la", "bgtz %1,%%pcrel(%2)", 0, 0, 0 },
+ { 0x0, 0x0, "bgtz", "r,la", "bgtz %1,%%b16(%2)", 0, 0, 0 },
{ 0x60000000, 0xfc0003e0, "bgtz", "r0:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bgez", "r,la", "bgez %1,%%pcrel(%2)", 0, 0, 0 },
+ { 0x0, 0x0, "bgez", "r,la", "bgez %1,%%b16(%2)", 0, 0, 0 },
{ 0x64000000, 0xfc00001f, "bgez", "r5:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "blez", "r,la", "blez %1,%%pcrel(%2)", 0, 0, 0 },
+ { 0x0, 0x0, "blez", "r,la", "blez %1,%%b16(%2)", 0, 0, 0 },
{ 0x64000000, 0xfc0003e0, "blez", "r0:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "beqz", "r,la", "beqz %1,%%pcrel(%2)", 0, 0, 0 },
+ { 0x0, 0x0, "beqz", "r,la", "beqz %1,%%b21(%2)", 0, 0, 0 },
{ 0x40000000, 0xfc000000, "beqz", "r5:5,sb0:5|10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bnez", "r,la", "bnez %1,%%pcrel(%2)", 0, 0, 0 },
+ { 0x0, 0x0, "bnez", "r,la", "bnez %1,%%b21(%2)", 0, 0, 0 },
{ 0x44000000, 0xfc000000, "bnez", "r5:5,sb0:5|10:16<<2", 0, 0, 0, 0 },
{ 0x0, 0x0, "jr", "r", "jirl $r0,%1,0", 0, 0, 0 },
{ 0x50000000, 0xfc000000, "b", "sb0:10|10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "b", "la", "b %%pcrel(%1)", 0, 0, 0 },
+ { 0x0, 0x0, "b", "la", "b %%b26(%1)", 0, 0, 0 },
{ 0x4c000000, 0xfc000000, "jirl", "r0:5,r5:5,s10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bl", "la", "bl %%pcrel(%1)", 0, 0, 0 },
+ { 0x0, 0x0, "bl", "la", "bl %%b26(%1)", 0, 0, 0 },
{ 0x54000000, 0xfc000000, "bl", "sb0:10|10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "beq", "r,r,la", "beq %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "beq", "r,r,la", "beq %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x58000000, 0xfc000000, "beq", "r5:5,r0:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bne", "r,r,la", "bne %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "bne", "r,r,la", "bne %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x5c000000, 0xfc000000, "bne", "r5:5,r0:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "blt", "r,r,la", "blt %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "blt", "r,r,la", "blt %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x60000000, 0xfc000000, "blt", "r5:5,r0:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bgt", "r,r,la", "bgt %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "bgt", "r,r,la", "bgt %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x60000000, 0xfc000000, "bgt", "r0:5,r5:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bge", "r,r,la", "bge %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "bge", "r,r,la", "bge %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x64000000, 0xfc000000, "bge", "r5:5,r0:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "ble", "r,r,la", "ble %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "ble", "r,r,la", "ble %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x64000000, 0xfc000000, "ble", "r0:5,r5:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bltu", "r,r,la", "bltu %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "bltu", "r,r,la", "bltu %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x68000000, 0xfc000000, "bltu", "r5:5,r0:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bgtu", "r,r,la", "bgtu %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "bgtu", "r,r,la", "bgtu %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x68000000, 0xfc000000, "bgtu", "r0:5,r5:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bgeu", "r,r,la", "bgeu %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "bgeu", "r,r,la", "bgeu %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x6c000000, 0xfc000000, "bgeu", "r5:5,r0:5,sb10:16<<2", 0, 0, 0, 0 },
- { 0x0, 0x0, "bleu", "r,r,la", "bleu %1,%2,%%pcrel(%3)", 0, 0, 0 },
+ { 0x0, 0x0, "bleu", "r,r,la", "bleu %1,%2,%%b16(%3)", 0, 0, 0 },
{ 0x6c000000, 0xfc000000, "bleu", "r0:5,r5:5,sb10:16<<2", 0, 0, 0, 0 },
{ 0 } /* Terminate the list. */
};
--
2.31.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 3/5 v1] LoongArch: gas: Add new reloc types.
2022-07-18 8:43 [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types liuzhensong
2022-07-18 8:43 ` [PATCH 2/5 v1] LoongArch:opcodes: " liuzhensong
@ 2022-07-18 8:43 ` liuzhensong
2022-07-18 8:43 ` [PATCH 4/5 v1] LoongArch: Move ifunc info to rela.dyn from rela.plt liuzhensong
` (3 subsequent siblings)
5 siblings, 0 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-18 8:43 UTC (permalink / raw)
To: binutils; +Cc: xuchenghua, mengqinggang, liuzhensong
Generate new relocate types while use new macro insns.
gas/config/
loongarch-lex.h
loongarch-parse.y
tc-loongarch.c
tc-loongarch.h
---
gas/config/loongarch-lex.h | 3 +
gas/config/loongarch-parse.y | 72 +++++-------------
gas/config/tc-loongarch.c | 140 ++++++++++++++++++++++++-----------
gas/config/tc-loongarch.h | 7 +-
4 files changed, 120 insertions(+), 102 deletions(-)
diff --git a/gas/config/loongarch-lex.h b/gas/config/loongarch-lex.h
index 59212442242..35d22dbdbc9 100644
--- a/gas/config/loongarch-lex.h
+++ b/gas/config/loongarch-lex.h
@@ -32,3 +32,6 @@ loongarch_parse_expr (const char *expr,
size_t max_reloc_num,
size_t *reloc_num,
offsetT *imm);
+bfd_reloc_code_real_type
+loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *l_r_name);
diff --git a/gas/config/loongarch-parse.y b/gas/config/loongarch-parse.y
index 710f854c74f..902d7204e8e 100644
--- a/gas/config/loongarch-parse.y
+++ b/gas/config/loongarch-parse.y
@@ -83,11 +83,11 @@ static const char *
my_getExpression (expressionS *ep, const char *str)
{
char *save_in, *ret;
+
if (*str == ':')
{
unsigned long j;
char *str_1 = (char *) str;
- str_1++;
j = strtol (str_1, &str_1, 10);
get_internal_label (ep, j, *str_1 == 'f');
return NULL;
@@ -104,65 +104,31 @@ static void
reloc (const char *op_c_str, const char *id_c_str, offsetT addend)
{
expressionS id_sym_expr;
+ bfd_reloc_code_real_type btype;
if (end <= top)
as_fatal (_("expr too huge"));
- if (id_c_str)
- {
- my_getExpression (&id_sym_expr, id_c_str);
- id_sym_expr.X_add_number += addend;
- }
+ /* For compatible old asm code. */
+ if (0 == strcmp (op_c_str, "plt"))
+ btype = BFD_RELOC_LARCH_B26;
else
- {
- id_sym_expr.X_op = O_constant;
- id_sym_expr.X_add_number = addend;
- }
+ btype = loongarch_larch_reloc_name_lookup (NULL, op_c_str);
- if (strcmp (op_c_str, "abs") == 0)
- {
- top->value = id_sym_expr;
- top->type = BFD_RELOC_LARCH_SOP_PUSH_ABSOLUTE;
- top++;
- }
- else if (strcmp (op_c_str, "pcrel") == 0)
- {
- top->value = id_sym_expr;
- top->type = BFD_RELOC_LARCH_SOP_PUSH_PCREL;
- top++;
- }
- else if (strcmp (op_c_str, "gprel") == 0)
- {
- top->value = id_sym_expr;
- top->type = BFD_RELOC_LARCH_SOP_PUSH_GPREL;
- top++;
- }
- else if (strcmp (op_c_str, "tprel") == 0)
- {
- top->value = id_sym_expr;
- top->type = BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL;
- top++;
- }
- else if (strcmp (op_c_str, "tlsgot") == 0)
- {
- top->value = id_sym_expr;
- top->type = BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT;
- top++;
- }
- else if (strcmp (op_c_str, "tlsgd") == 0)
- {
- top->value = id_sym_expr;
- top->type = BFD_RELOC_LARCH_SOP_PUSH_TLS_GD;
- top++;
- }
- else if (strcmp (op_c_str, "plt") == 0)
- {
- top->value = id_sym_expr;
- top->type = BFD_RELOC_LARCH_SOP_PUSH_PLT_PCREL;
- top++;
- }
+ if (id_c_str)
+ {
+ my_getExpression (&id_sym_expr, id_c_str);
+ id_sym_expr.X_add_number += addend;
+ }
else
- as_fatal (_("unknown reloc hint: %s"), op_c_str);
+ {
+ id_sym_expr.X_op = O_constant;
+ id_sym_expr.X_add_number = addend;
+ }
+
+ top->value = id_sym_expr;
+ top->type = btype;
+ top++;
}
static void
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 08203d291bd..e9c1a536505 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -362,18 +362,6 @@ loongarch_mach (void)
static const expressionS const_0 = { .X_op = O_constant, .X_add_number = 0 };
-static const char *
-my_getExpression (expressionS *ep, const char *str)
-{
- char *save_in, *ret;
- save_in = input_line_pointer;
- input_line_pointer = (char *) str;
- expression (ep);
- ret = input_line_pointer;
- input_line_pointer = save_in;
- return ret;
-}
-
static void
s_loongarch_align (int arg)
{
@@ -480,11 +468,6 @@ get_internal_label (expressionS *label_expr, unsigned long label,
label_expr->X_add_number = 0;
}
-extern int loongarch_parse_expr (const char *expr,
- struct reloc_info *reloc_stack_top,
- size_t max_reloc_num, size_t *reloc_num,
- offsetT *imm_if_no_reloc);
-
static int
is_internal_label (const char *c_str)
{
@@ -652,6 +635,15 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
as_fatal (
_("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"),
esc_ch1, esc_ch2, bit_field, arg);
+ if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16
+ && ip->reloc_info[0].type < BFD_RELOC_LARCH_RELAX)
+ {
+ /* As we compact stack-relocs, it is no need for pop operation.
+ But break out until here in order to check the imm field.
+ May be reloc_num > 1 if implement relax? */
+ ip->reloc_num += reloc_num;
+ break;
+ }
reloc_num++;
ip->reloc_num += reloc_num;
ip->reloc_info[ip->reloc_num - 1].type = reloc_type;
@@ -767,7 +759,12 @@ get_loongarch_opcode (struct loongarch_cl_insn *insn)
{
ase->name_hash_entry = str_htab_create ();
for (it = ase->opcodes; it->name; it++)
- str_hash_insert (ase->name_hash_entry, it->name, (void *) it, 0);
+ {
+ if ((!it->include || (it->include && *it->include))
+ && (!it->exclude || (it->exclude && !(*it->exclude))))
+ str_hash_insert (ase->name_hash_entry, it->name,
+ (void *) it, 0);
+ }
}
if ((it = str_hash_find (ase->name_hash_entry, insn->name)) == NULL)
@@ -800,10 +797,11 @@ static int
check_this_insn_before_appending (struct loongarch_cl_insn *ip)
{
int ret = 0;
- if (strcmp (ip->name, "la.abs") == 0)
+
+ if (strncmp (ip->name, "la.abs", 6) == 0)
{
ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_MARK_LA;
- my_getExpression (&ip->reloc_info[ip->reloc_num].value, ip->arg_strs[1]);
+ ip->reloc_info[ip->reloc_num].value = const_0;
ip->reloc_num++;
}
else if (ip->insn->mask == 0xffff8000
@@ -980,6 +978,7 @@ assember_macro_helper (const char *const args[], void *context_ptr)
ret = loongarch_expand_macro (insns_buf, arg_strs, NULL, NULL,
sizeof (args_buf));
}
+
return ret;
}
@@ -1096,6 +1095,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
static int64_t stack_top;
static int last_reloc_is_sop_push_pcrel_1 = 0;
int last_reloc_is_sop_push_pcrel = last_reloc_is_sop_push_pcrel_1;
+ segT sub_segment;
last_reloc_is_sop_push_pcrel_1 = 0;
char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
@@ -1104,26 +1104,40 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL:
case BFD_RELOC_LARCH_SOP_PUSH_TLS_GD:
case BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT:
- case BFD_RELOC_LARCH_SOP_PUSH_PCREL:
- case BFD_RELOC_LARCH_SOP_PUSH_PLT_PCREL:
+ case BFD_RELOC_LARCH_TLS_LE_HI20:
+ case BFD_RELOC_LARCH_TLS_LE_LO12:
+ case BFD_RELOC_LARCH_TLS_LE64_LO20:
+ case BFD_RELOC_LARCH_TLS_LE64_HI12:
+ case BFD_RELOC_LARCH_TLS_IE_PC_HI20:
+ case BFD_RELOC_LARCH_TLS_IE_PC_LO12:
+ case BFD_RELOC_LARCH_TLS_IE64_PC_LO20:
+ case BFD_RELOC_LARCH_TLS_IE64_PC_HI12:
+ case BFD_RELOC_LARCH_TLS_IE64_HI20:
+ case BFD_RELOC_LARCH_TLS_IE64_LO12:
+ case BFD_RELOC_LARCH_TLS_IE64_LO20:
+ case BFD_RELOC_LARCH_TLS_IE64_HI12:
+ case BFD_RELOC_LARCH_TLS_LD_PC_HI20:
+ case BFD_RELOC_LARCH_TLS_LD64_HI20:
+ case BFD_RELOC_LARCH_TLS_GD_PC_HI20:
+ case BFD_RELOC_LARCH_TLS_GD64_HI20:
+ /* Add tls lo (got_lo reloc type). */
if (fixP->fx_addsy == NULL)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Relocation against a constant"));
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
- if (fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL
- || fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_TLS_GD
- || fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT)
- S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ case BFD_RELOC_LARCH_SOP_PUSH_PCREL:
+ if (fixP->fx_addsy == NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Relocation against a constant"));
- if (fixP->fx_r_type == BFD_RELOC_LARCH_SOP_PUSH_PCREL)
- {
- last_reloc_is_sop_push_pcrel_1 = 1;
- if (S_GET_SEGMENT (fixP->fx_addsy) == seg)
- stack_top = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
- - (fixP->fx_where + fixP->fx_frag->fr_address));
- else
- stack_top = 0;
- }
+ last_reloc_is_sop_push_pcrel_1 = 1;
+ if (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ stack_top = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
+ - (fixP->fx_where + fixP->fx_frag->fr_address));
+ else
+ stack_top = 0;
break;
case BFD_RELOC_LARCH_SOP_POP_32_S_10_5:
@@ -1143,11 +1157,24 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_64:
case BFD_RELOC_32:
+ case BFD_RELOC_24:
+ case BFD_RELOC_16:
+ case BFD_RELOC_8:
+
+ if (fixP->fx_r_type == BFD_RELOC_32
+ && fixP->fx_addsy && fixP->fx_subsy
+ && (sub_segment = S_GET_SEGMENT (fixP->fx_subsy))
+ && strcmp (sub_segment->name, ".eh_frame") == 0
+ && S_GET_VALUE (fixP->fx_subsy)
+ == fixP->fx_frag->fr_address + fixP->fx_where)
+ {
+ fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL;
+ fixP->fx_subsy = NULL;
+ break;
+ }
+
if (fixP->fx_subsy)
{
- case BFD_RELOC_24:
- case BFD_RELOC_16:
- case BFD_RELOC_8:
fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
fixP->fx_next->fx_addsy = fixP->fx_subsy;
fixP->fx_next->fx_subsy = NULL;
@@ -1190,6 +1217,25 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
}
break;
+ case BFD_RELOC_LARCH_B16:
+ case BFD_RELOC_LARCH_B21:
+ case BFD_RELOC_LARCH_B26:
+ if (fixP->fx_addsy == NULL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _ ("Relocation against a constant."));
+ }
+ if (S_GET_SEGMENT (fixP->fx_addsy) == seg
+ && !S_FORCE_RELOC (fixP->fx_addsy, 1))
+ {
+ int64_t sym_addend = S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset;
+ int64_t pc = fixP->fx_where + fixP->fx_frag->fr_address;
+ fix_reloc_insn (fixP, sym_addend - pc, buf);
+ fixP->fx_done = 1;
+ }
+
+ break;
+
default:
break;
}
@@ -1210,6 +1256,18 @@ md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
return 0;
}
+int
+loongarch_fix_adjustable (fixS *fix)
+{
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERNAL (fix->fx_addsy)
+ || S_IS_WEAK (fix->fx_addsy)
+ || S_FORCE_RELOC (fix->fx_addsy, true))
+ return 0;
+
+ return 1;
+}
+
/* Translate internal representation of relocation info to BFD target
format. */
arelent *
@@ -1249,12 +1307,6 @@ loongarch_cfi_frame_initial_instructions (void)
cfi_add_CFA_def_cfa_register (3 /* $sp */);
}
-int
-loongarch_dwarf2_addr_size (void)
-{
- return LARCH_opts.ase_lp64 ? 8 : 4;
-}
-
void
tc_loongarch_parse_to_dw2regnum (expressionS *exp)
{
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
index 2664da59f51..f05926d7d67 100644
--- a/gas/config/tc-loongarch.h
+++ b/gas/config/tc-loongarch.h
@@ -49,7 +49,8 @@ extern int loongarch_relax_frag (asection *, struct frag *, long);
/* This is called to see whether a reloc against a defined symbol
should be converted into a reloc against a section. */
-#define tc_fix_adjustable(fixp) 0
+extern int loongarch_fix_adjustable (struct fix *fix);
+#define tc_fix_adjustable(fixp) loongarch_fix_adjustable(fixp)
/* Values passed to md_apply_fix don't include symbol values. */
#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1
@@ -59,10 +60,6 @@ extern int loongarch_relax_frag (asection *, struct frag *, long);
#define TARGET_USE_CFIPOP 1
#define DWARF2_DEFAULT_RETURN_COLUMN 1 /* $ra. */
#define DWARF2_CIE_DATA_ALIGNMENT -4
-extern int loongarch_dwarf2_addr_size (void);
-#define DWARF2_FDE_RELOC_SIZE loongarch_dwarf2_addr_size ()
-#define DWARF2_ADDR_SIZE(bfd) loongarch_dwarf2_addr_size ()
-#define CFI_DIFF_EXPR_OK 0
#define tc_cfi_frame_initial_instructions \
loongarch_cfi_frame_initial_instructions
--
2.31.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 4/5 v1] LoongArch: Move ifunc info to rela.dyn from rela.plt.
2022-07-18 8:43 [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types liuzhensong
2022-07-18 8:43 ` [PATCH 2/5 v1] LoongArch:opcodes: " liuzhensong
2022-07-18 8:43 ` [PATCH 3/5 v1] LoongArch: gas: " liuzhensong
@ 2022-07-18 8:43 ` liuzhensong
2022-07-18 11:45 ` Xi Ruoyao
2022-07-18 16:27 ` Xi Ruoyao
2022-07-18 8:43 ` [PATCH 5/5 v1] LoongArch: Delete R_LARCH_NONE from dynamic info liuzhensong
` (2 subsequent siblings)
5 siblings, 2 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-18 8:43 UTC (permalink / raw)
To: binutils; +Cc: xuchenghua, mengqinggang, liuzhensong
Delete R_LARCH_IRELATIVE from dynamic loader (glibc ld.so) when
loading lazy function (rela.plt section).
In dynamic programes, move ifunc dynamic relocate info to section
srelgot from srelplt.
bfd/
elfnn-loongarch.c
---
bfd/elfnn-loongarch.c | 322 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 310 insertions(+), 12 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 4eeaeb44eff..5bb7596e5d0 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -1207,6 +1207,259 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
return true;
}
+/* Based function _bfd_elf_allocate_ifunc_dyn_relocs.
+ For local def and ref ifunc,
+ dynamic relocations are stored in
+ 1. rel[a].irelifunc section in PIC object.
+ 2. rel[a].srelgot section in dynamic executable.
+ 3. rel[a].irelplt section in static executable.
+ Change ifunc dynamic info from srelplt to srelgot.
+ In loader, remove R_LARCH_IRELACTIVE from rela lazy in ld.so. */
+
+static bool
+local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ struct elf_dyn_relocs **head,
+ unsigned int plt_entry_size,
+ unsigned int plt_header_size,
+ unsigned int got_entry_size,
+ bool avoid_plt)
+{
+ asection *plt, *gotplt, *relplt;
+ struct elf_dyn_relocs *p;
+ unsigned int sizeof_reloc;
+ const struct elf_backend_data *bed;
+ struct elf_link_hash_table *htab;
+ /* If AVOID_PLT is TRUE, don't use PLT if possible. */
+ bool use_plt = !avoid_plt || h->plt.refcount > 0;
+ bool need_dynreloc = !use_plt || bfd_link_pic (info);
+
+ /* When a PIC object references a STT_GNU_IFUNC symbol defined
+ in executable or it isn't referenced via PLT, the address of
+ the resolved function may be used. But in non-PIC executable,
+ the address of its plt slot may be used. Pointer equality may
+ not work correctly. PIE or non-PLT reference should be used if
+ pointer equality is required here.
+
+ If STT_GNU_IFUNC symbol is defined in position-dependent executable,
+ backend should change it to the normal function and set its address
+ to its PLT entry which should be resolved by R_*_IRELATIVE at
+ run-time. All external references should be resolved to its PLT in
+ executable. */
+ if (!need_dynreloc
+ && !(bfd_link_pde (info) && h->def_regular)
+ && (h->dynindx != -1
+ || info->export_dynamic)
+ && h->pointer_equality_needed)
+ {
+ info->callbacks->einfo
+ /* xgettext:c-format. */
+ (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
+ "equality in `%pB' can not be used when making an "
+ "executable; recompile with -fPIE and relink with -pie\n"),
+ h->root.root.string,
+ h->root.u.def.section->owner);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ htab = elf_hash_table (info);
+
+ /* When the symbol is marked with regular reference, if PLT isn't used
+ or we are building a PIC object, we must keep dynamic relocation
+ if there is non-GOT reference and use PLT if there is PC-relative
+ reference. */
+ if (need_dynreloc && h->ref_regular)
+ {
+ bool keep = false;
+ for (p = *head; p != NULL; p = p->next)
+ if (p->count)
+ {
+ h->non_got_ref = 1;
+ /* Need dynamic relocations for non-GOT reference. */
+ keep = true;
+ if (p->pc_count)
+ {
+ /* Must use PLT for PC-relative reference. */
+ use_plt = true;
+ need_dynreloc = bfd_link_pic (info);
+ break;
+ }
+ }
+ if (keep)
+ goto keep;
+ }
+
+ /* Support garbage collection against STT_GNU_IFUNC symbols. */
+ if (h->plt.refcount <= 0 && h->got.refcount <= 0)
+ {
+ h->got = htab->init_got_offset;
+ h->plt = htab->init_plt_offset;
+ *head = NULL;
+ return true;
+ }
+
+ /* Return and discard space for dynamic relocations against it if
+ it is never referenced. */
+ if (!h->ref_regular)
+ {
+ if (h->plt.refcount > 0
+ || h->got.refcount > 0)
+ abort ();
+ h->got = htab->init_got_offset;
+ h->plt = htab->init_plt_offset;
+ *head = NULL;
+ return true;
+ }
+
+ keep:
+ bed = get_elf_backend_data (info->output_bfd);
+ if (bed->rela_plts_and_copies_p)
+ sizeof_reloc = bed->s->sizeof_rela;
+ else
+ sizeof_reloc = bed->s->sizeof_rel;
+
+ /* When building a static executable, use iplt, igot.plt and
+ rel[a].iplt sections for STT_GNU_IFUNC symbols. */
+ if (htab->splt != NULL)
+ {
+ plt = htab->splt;
+ gotplt = htab->sgotplt;
+ /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */
+ relplt = htab->srelgot;
+
+ /* If this is the first plt entry and PLT is used, make room for
+ the special first entry. */
+ if (plt->size == 0 && use_plt)
+ plt->size += plt_header_size;
+ }
+ else
+ {
+ plt = htab->iplt;
+ gotplt = htab->igotplt;
+ relplt = htab->irelplt;
+ }
+
+ if (use_plt)
+ {
+ /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
+ the original value for R_*_IRELATIVE. */
+ h->plt.offset = plt->size;
+
+ /* Make room for this entry in the plt/iplt section. */
+ plt->size += plt_entry_size;
+
+ /* We also need to make an entry in the got.plt/got.iplt section,
+ which will be placed in the got section by the linker script. */
+ gotplt->size += got_entry_size;
+ }
+
+ /* We also need to make an entry in the rel[a].plt/.rel[a].iplt
+ section for GOTPLT relocation if PLT is used. */
+ if (use_plt)
+ {
+ relplt->size += sizeof_reloc;
+ relplt->reloc_count++;
+ }
+
+ /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
+ there is a non-GOT reference in a PIC object or PLT isn't used. */
+ if (!need_dynreloc || !h->non_got_ref)
+ *head = NULL;
+
+ /* Finally, allocate space. */
+ p = *head;
+ if (p != NULL)
+ {
+ bfd_size_type count = 0;
+ do
+ {
+ count += p->count;
+ p = p->next;
+ }
+ while (p != NULL);
+
+ htab->ifunc_resolvers = count != 0;
+
+ /* Dynamic relocations are stored in
+ 1. rel[a].srelgot section in PIC object.
+ 2. rel[a].srelgot section in dynamic executable.
+ 3. rel[a].irelplt section in static executable. */
+ if (htab->splt != NULL)
+ htab->srelgot->size += count * sizeof_reloc;
+ else
+ {
+ relplt->size += count * sizeof_reloc;
+ relplt->reloc_count += count;
+ }
+ }
+
+ /* For STT_GNU_IFUNC symbol, got.plt has the real function address
+ and got has the PLT entry adddress. We will load the GOT entry
+ with the PLT entry in finish_dynamic_symbol if it is used. For
+ branch, it uses got.plt. For symbol value, if PLT is used,
+ 1. Use got.plt in a PIC object if it is forced local or not
+ dynamic.
+ 2. Use got.plt in a non-PIC object if pointer equality isn't
+ needed.
+ 3. Use got.plt in PIE.
+ 4. Use got.plt if got isn't used.
+ 5. Otherwise use got so that it can be shared among different
+ objects at run-time.
+ If PLT isn't used, always use got for symbol value.
+ We only need to relocate got entry in PIC object or in dynamic
+ executable without PLT. */
+ if (use_plt
+ && (h->got.refcount <= 0
+ || (bfd_link_pic (info)
+ && (h->dynindx == -1
+ || h->forced_local))
+ || (
+ !h->pointer_equality_needed)
+ || htab->sgot == NULL))
+ {
+ /* Use got.plt. */
+ h->got.offset = (bfd_vma) -1;
+ }
+ else
+ {
+ if (!use_plt)
+ {
+ /* PLT isn't used. */
+ h->plt.offset = (bfd_vma) -1;
+ }
+ if (h->got.refcount <= 0)
+ {
+ /* GOT isn't need when there are only relocations for static
+ pointers. */
+ h->got.offset = (bfd_vma) -1;
+ }
+ else
+ {
+ h->got.offset = htab->sgot->size;
+ htab->sgot->size += got_entry_size;
+ /* Need to relocate the GOT entry in a PIC object or PLT isn't
+ used. Otherwise, the GOT entry will be filled with the PLT
+ entry and dynamic GOT relocation isn't needed. */
+ if (need_dynreloc)
+ {
+ /* For non-static executable, dynamic GOT relocation is in
+ rel[a].got section, but for static executable, it is
+ in rel[a].iplt section. */
+ if (htab->splt != NULL)
+ htab->srelgot->size += sizeof_reloc;
+ else
+ {
+ relplt->size += sizeof_reloc;
+ relplt->reloc_count++;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
/* Allocate space in .plt, .got and associated reloc sections for
ifunc dynamic relocs. */
@@ -1234,12 +1487,23 @@ elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
here if it is defined and referenced in a non-shared object. */
if (h->type == STT_GNU_IFUNC && h->def_regular)
- return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
+ {
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ return local_allocate_ifunc_dyn_relocs (info, h,
&h->dyn_relocs,
PLT_ENTRY_SIZE,
PLT_HEADER_SIZE,
GOT_ENTRY_SIZE,
false);
+ else
+ return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
+ &h->dyn_relocs,
+ PLT_ENTRY_SIZE,
+ PLT_HEADER_SIZE,
+ GOT_ENTRY_SIZE,
+ false);
+
+ }
return true;
}
@@ -2175,7 +2439,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+ h->root.u.def.section->output_offset);
if (htab->elf.splt != NULL)
- sreloc = htab->elf.srelplt;
+ sreloc = htab->elf.srelgot;
else
sreloc = htab->elf.irelplt;
}
@@ -2818,10 +3082,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_LARCH_PCALA64_LO20:
case R_LARCH_PCALA64_HI12:
if (h && h->plt.offset != MINUS_ONE)
- {
- BFD_ASSERT (rel->r_addend == 0);
- relocation = sec_addr (plt) + h->plt.offset;
- }
+ relocation = sec_addr (plt) + h->plt.offset;
else
relocation += rel->r_addend;
@@ -3239,7 +3500,10 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
plt = htab->elf.splt;
gotplt = htab->elf.sgotplt;
- relplt = htab->elf.srelplt;
+ if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
+ relplt = htab->elf.srelgot;
+ else
+ relplt = htab->elf.srelplt;
plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
got_address =
sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
@@ -3274,11 +3538,45 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
rela.r_offset = got_address;
- /* Fill in the entry in the rela.plt section. */
- rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
- rela.r_addend = 0;
- loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
- bed->s->swap_reloca_out (output_bfd, &rela, loc);
+ /* TRUE if this is a PLT reference to a local IFUNC. */
+ if (PLT_LOCAL_IFUNC_P (info, h)
+ && (relplt == htab->elf.srelgot
+ || relplt == htab->elf.irelplt))
+ {
+ {
+ rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
+ rela.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ /* Find the space after dyn sort. */
+ {
+ Elf_Internal_Rela *dyn = (Elf_Internal_Rela *)relplt->contents;
+ bool fill = false;
+ for (;dyn < dyn + relplt->size / sizeof (*dyn); dyn++)
+ {
+ if (0 == dyn->r_offset)
+ {
+ bed->s->swap_reloca_out (output_bfd, &rela,
+ (bfd_byte *)dyn);
+ relplt->reloc_count++;
+ fill = true;
+ break;
+ }
+ }
+ BFD_ASSERT (fill);
+ }
+
+ }
+ else
+ {
+ /* Fill in the entry in the rela.plt section. */
+ rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
+ rela.r_addend = 0;
+ loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
+ bed->s->swap_reloca_out (output_bfd, &rela, loc);
+ }
if (!h->def_regular)
{
--
2.31.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 5/5 v1] LoongArch: Delete R_LARCH_NONE from dynamic info.
2022-07-18 8:43 [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types liuzhensong
` (2 preceding siblings ...)
2022-07-18 8:43 ` [PATCH 4/5 v1] LoongArch: Move ifunc info to rela.dyn from rela.plt liuzhensong
@ 2022-07-18 8:43 ` liuzhensong
2022-07-18 10:06 ` [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types WANG Xuerui
2022-07-19 4:29 ` Xi Ruoyao
5 siblings, 0 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-18 8:43 UTC (permalink / raw)
To: binutils; +Cc: xuchenghua, mengqinggang, liuzhensong
Some R_LARCH_64 in section .eh_frame will to generate
R_LARCH_NONE, we change relocation to R_LARCH_32_PCREL
from R_LARCH_64 in setction .eh_frame and not generate
dynamic relocation for R_LARCH_32_PCREL.
Add New relocate type R_LARCH_32_PCREL for .eh_frame.
include/elf/
loongarch.h
bfd/
bfd/bfd-in2.h
libbfd.h
reloc.c
elfxx-loongarch.c
elfnn-loongarch.c
gas/config/
tc-loongarch.c
binutils/
readelf.c
ld/testsuite/ld-elf/
eh5.d
---
bfd/bfd-in2.h | 1 +
bfd/elfnn-loongarch.c | 11 +++++++++++
bfd/elfxx-loongarch.c | 19 ++++++++++++++++++-
bfd/libbfd.h | 1 +
bfd/reloc.c | 3 +++
binutils/readelf.c | 2 ++
include/elf/loongarch.h | 5 ++++-
ld/testsuite/ld-elf/eh5.d | 2 +-
8 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index a71b3e82057..53abf36477f 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6309,6 +6309,7 @@ assembler and not (currently) written to any object files. */
BFD_RELOC_LARCH_TLS_LD64_HI20,
BFD_RELOC_LARCH_TLS_GD_PC_HI20,
BFD_RELOC_LARCH_TLS_GD64_HI20,
+ BFD_RELOC_LARCH_32_PCREL,
BFD_RELOC_LARCH_RELAX,
BFD_RELOC_UNUSED };
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 5bb7596e5d0..44b8d6dca9b 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -2011,6 +2011,17 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
bfd_put (bits, input_bfd, opr1 - value, contents + rel->r_offset);
break;
+ /* For eh_frame and debug info. */
+ case R_LARCH_32_PCREL:
+ value -= sec_addr (input_section) + rel->r_offset;
+ value += rel->r_addend;
+ bfd_vma word = bfd_get (howto->bitsize, input_bfd,
+ contents + rel->r_offset);
+ word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
+ bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
+ r = bfd_reloc_ok;
+ break;
+
/* New reloc type.
R_LARCH_B16 ~ R_LARCH_TLS_GD64_HI20. */
case R_LARCH_B16:
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 1f6346ef5f3..1a4f99a8927 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1327,7 +1327,24 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
reloc_bits, /* adjust_reloc_bits */
"gd64_hi20"), /* larch_reloc_type_name */
- LOONGARCH_HOWTO (R_LARCH_RELAX, /* type (99). */
+ LOONGARCH_HOWTO (R_LARCH_32_PCREL, /* type (99). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 32, /* bitsize. */
+ true, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_32_PCREL", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false, /* pcrel_offset */
+ BFD_RELOC_LARCH_32_PCREL, /* bfd_reloc_code_real_type */
+ NULL, /* adjust_reloc_bits */
+ NULL), /* larch_reloc_type_name */
+
+ LOONGARCH_HOWTO (R_LARCH_RELAX, /* type (100). */
0, /* rightshift */
1, /* size */
0, /* bitsize */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index b23ae4b755c..0b8610524e1 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3492,6 +3492,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_LARCH_TLS_LD64_HI20",
"BFD_RELOC_LARCH_TLS_GD_PC_HI20",
"BFD_RELOC_LARCH_TLS_GD64_HI20",
+ "BFD_RELOC_LARCH_32_PCREL",
"BFD_RELOC_LARCH_RELAX",
"@@overflow: BFD_RELOC_UNUSED@@",
};
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 836fa162108..6f092235369 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8304,6 +8304,9 @@ ENUMX
ENUMX
BFD_RELOC_LARCH_TLS_GD64_HI20
+ENUMX
+ BFD_RELOC_LARCH_32_PCREL
+
ENUMX
BFD_RELOC_LARCH_RELAX
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 0f5977bc072..74f59d49fdc 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -14388,6 +14388,8 @@ is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
case EM_AVR_OLD:
case EM_AVR:
return reloc_type == 36; /* R_AVR_32_PCREL. */
+ case EM_LOONGARCH:
+ return reloc_type == 99; /* R_LARCH_32_PCREL. */
case EM_MICROBLAZE:
return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
case EM_OR1K:
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index 863dad3a371..9e0a5217f60 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -223,8 +223,11 @@ RELOC_NUMBER (R_LARCH_TLS_GD_PC_HI20, 97)
%gd64_hi20 (sym). */
RELOC_NUMBER (R_LARCH_TLS_GD64_HI20, 98)
+/* For eh_frame and debug info. */
+RELOC_NUMBER (R_LARCH_32_PCREL, 99)
+
/* RELAX. */
-RELOC_NUMBER (R_LARCH_RELAX, 99)
+RELOC_NUMBER (R_LARCH_RELAX, 100)
END_RELOC_NUMBERS (R_LARCH_count)
diff --git a/ld/testsuite/ld-elf/eh5.d b/ld/testsuite/ld-elf/eh5.d
index d614251587c..4a697482355 100644
--- a/ld/testsuite/ld-elf/eh5.d
+++ b/ld/testsuite/ld-elf/eh5.d
@@ -4,7 +4,7 @@
#ld:
#readelf: -wf
#target: [check_as_cfi]
-#xfail: alpha-*-*ecoff hppa64-*-* tile*-*-* visium-*-* loongarch64-*-*
+#xfail: alpha-*-*ecoff hppa64-*-* tile*-*-* visium-*-*
Contents of the .eh_frame section:
--
2.31.1
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-18 8:43 [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types liuzhensong
` (3 preceding siblings ...)
2022-07-18 8:43 ` [PATCH 5/5 v1] LoongArch: Delete R_LARCH_NONE from dynamic info liuzhensong
@ 2022-07-18 10:06 ` WANG Xuerui
2022-07-18 11:33 ` Xi Ruoyao
` (2 more replies)
2022-07-19 4:29 ` Xi Ruoyao
5 siblings, 3 replies; 24+ messages in thread
From: WANG Xuerui @ 2022-07-18 10:06 UTC (permalink / raw)
To: liuzhensong, binutils; +Cc: xuchenghua, mengqinggang, Xi Ruoyao, Fangrui Song
(Adding Ruoyao and MaskRay to CC, who might be interested in this
development as well, as it concerns the linker implementation.)
On 2022/7/18 16:43, liuzhensong wrote:
> This is the v1 version of patches to support new relocs for LoongArch.
>
> The new reloc types docnments are on:
> https://github.com/loongson/LoongArch-Documentation/pull/57/files
>
> The testsuite status:
>
> === binutils Summary ===
>
> # of expected passes 241
> # of unsupported tests 6
>
> === gas Summary ===
>
> # of expected passes 270
> # of unsupported tests 7
>
> === ld Summary ===
>
> # of expected passes 1457
> # of expected failures 11
> # of untested testcases 1
> # of unsupported tests 154
>
I assume the content above are the "cover letter".
BTW: you can generate a proper patch series with `git format-patch -vN
--cover-letter <base>`; I think the mails in this series were manually
edited by you since the "v1" is wrongly placed (it's usually "[PATCH vN
NN/NN]").
> Add new reloc types support, the new relocate type
> definition depends which operation needs of linker.
"Define new reloc types according to linker needs" could be enough.
>
>
> ---
> bfd/bfd-in2.h | 36 ++
> bfd/elfnn-loongarch.c | 1194 ++++++++++++++++++++++------------
> bfd/elfxx-loongarch.c | 1354 +++++++++++++++++++++++++++++----------
> bfd/elfxx-loongarch.h | 4 +
> bfd/libbfd.h | 36 ++
> bfd/reloc.c | 79 +++
> include/elf/loongarch.h | 142 +++-
> 7 files changed, 2095 insertions(+), 750 deletions(-)
>
> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> index 4e1182e93d4..a71b3e82057 100644
> --- a/bfd/bfd-in2.h
> +++ b/bfd/bfd-in2.h
> @@ -6274,6 +6274,42 @@ assembler and not (currently) written to any object files. */
> BFD_RELOC_LARCH_SUB24,
> BFD_RELOC_LARCH_SUB32,
> BFD_RELOC_LARCH_SUB64,
> + BFD_RELOC_LARCH_B16,
> + BFD_RELOC_LARCH_B21,
> + BFD_RELOC_LARCH_B26,
> + BFD_RELOC_LARCH_ABS_HI20,
> + BFD_RELOC_LARCH_ABS_LO12,
> + BFD_RELOC_LARCH_ABS64_LO20,
> + BFD_RELOC_LARCH_ABS64_HI12,
> + BFD_RELOC_LARCH_PCALA_HI20,
> + BFD_RELOC_LARCH_PCALA_LO12,
> + BFD_RELOC_LARCH_PCALA64_LO20,
> + BFD_RELOC_LARCH_PCALA64_HI12,
> + BFD_RELOC_LARCH_GOT_PC_HI20,
> + BFD_RELOC_LARCH_GOT_PC_LO12,
> + BFD_RELOC_LARCH_GOT64_PC_LO20,
> + BFD_RELOC_LARCH_GOT64_PC_HI12,
> + BFD_RELOC_LARCH_GOT64_HI20,
> + BFD_RELOC_LARCH_GOT64_LO12,
> + BFD_RELOC_LARCH_GOT64_LO20,
> + BFD_RELOC_LARCH_GOT64_HI12,
> + BFD_RELOC_LARCH_TLS_LE_HI20,
> + BFD_RELOC_LARCH_TLS_LE_LO12,
> + BFD_RELOC_LARCH_TLS_LE64_LO20,
> + BFD_RELOC_LARCH_TLS_LE64_HI12,
> + BFD_RELOC_LARCH_TLS_IE_PC_HI20,
> + BFD_RELOC_LARCH_TLS_IE_PC_LO12,
> + BFD_RELOC_LARCH_TLS_IE64_PC_LO20,
> + BFD_RELOC_LARCH_TLS_IE64_PC_HI12,
> + BFD_RELOC_LARCH_TLS_IE64_HI20,
> + BFD_RELOC_LARCH_TLS_IE64_LO12,
> + BFD_RELOC_LARCH_TLS_IE64_LO20,
> + BFD_RELOC_LARCH_TLS_IE64_HI12,
> + BFD_RELOC_LARCH_TLS_LD_PC_HI20,
> + BFD_RELOC_LARCH_TLS_LD64_HI20,
> + BFD_RELOC_LARCH_TLS_GD_PC_HI20,
> + BFD_RELOC_LARCH_TLS_GD64_HI20,
I think I've voiced my concerns over the naming of these ops multiple
times already; the primary comment ([1]; in English) was posted back in
May but no one in your team responded.
Reproducing the content (and adjusting a little) here:
Overall in a good direction (and IMHO the direction everyone should have
taken in the first place), thanks! A few suggestions though:
Some of the names can be a bit hard to understand, for example ABS_LO12,
ABS_HI20, ABS64_LO20 and ABS64_HI12; these are ambiguous on a first
look, do you use the latter two instead of the former for 64-bit
absolute relocs? (The answer is "no"; you use all 4. The latter two
actually express the higher 32-bit half.)
After having trained your intuition to work in "the Loongson way",
you'll then have to mentally add the "lower/higher half" and "width"
together to get a picture of the bit-field being expressed. It could be
better to somehow directly show the 0(LO)/12/32/52 inside those names.
Plus, currently it's implied that a particular relocation type is
somehow bound to a specific instruction, that's being used by the
reference implementation (binutils) for the type today. This is being a
bit too specific, and could change, as future instructions emerge with
similar or identical format. (BTW no one really understand what "ALA"
means in "PCALA"; the insn is named "PCALAU12I", the "U12I" part is
similar to "LU12I.W" thus understandable, and PC is obvious, but no
explanation for "ALA" exists anywhere). It's better to express the
"destination" not in terms of instruction names or vague
"LO12/HI20/LO20/HI12" specifiers, but in terms of actual *instruction
word slots* being filled. This way it's immediately obvious for anyone
what place in the insn word the reloc is going to write to, without
having to dig into actual linker code. However, you don't officially
have a naming scheme for these, so I guess that's why you have to invent
names (and be different with others & prior work).
I have drafted my scheme back in November 2021, which I posted at [2] a
while ago; the approach is extremely similar (IMO there's only one
possible way to implement the more traditional scheme), but my version
has adopted the operand slot naming scheme of loongarch-opcodes ([3];
the convention document is edited and posted at [4] for inclusion in
official LoongArch docs collection) and the more direct LO/12/32/52
names for bit-field offsets (width is implied by the destination slot).
Hope this would be useful.
Again, I may sound like a bikeshedder, but IMO better names benefit
everyone in the long term. I for one definitely don't want to see all
four of "LO12/HI20/LO20/HI12" (they refer to the two 32-bit halves of a
64-bit value, not two ways to segment one 32-bit value), nor
"B16/B21/B26" (which are more different than you might think).
[1]: https://github.com/loongson/LoongArch-Documentation/pull/50
[2]:
https://github.com/loongson/binutils-gdb/issues/134#issuecomment-1110510582
[3]: https://github.com/loongson-community/loongarch-opcodes
[4]: https://github.com/loongson/LoongArch-Documentation/pull/56
FYI, I did make a list of my suggested names for these reloc types
("BFD_RELOC_LARCH_" abbreviated to "B_R_L_"):
Original name Suggested name
------------- --------------
B_R_L_B16 B_R_L_PCREL_SK16 *1
B_R_L_B21 B_R_L_PCREL_SD5K16
B_R_L_B26 B_R_L_PCREL_SD10K16
B_R_L_ABS_LO12 B_R_L_ABS_0_SK12
B_R_L_ABS_HI20 B_R_L_ABS_12_SJ20
B_R_L_ABS64_LO20 B_R_L_ABS_32_SJ20
B_R_L_ABS64_HI12 B_R_L_ABS_52_SK12
B_R_L_PCALA_LO12 B_R_L_PCALA_0_SK12 *2
B_R_L_PCALA_HI20 B_R_L_PCALA_12_SJ20
B_R_L_PCALA64_LO20 B_R_L_PCALA_32_SJ20 *3
B_R_L_PCALA64_HI12 B_R_L_PCALA_52_SK12
B_R_L_GOT_PC_LO12 B_R_L_GOT_PCALA_0_SK12 *4
B_R_L_GOT_PC_HI20 B_R_L_GOT_PCALA_12_SJ20
B_R_L_GOT64_PC_LO20 B_R_L_GOT_PCALA_32_SJ20
B_R_L_GOT64_PC_HI12 B_R_L_GOT_PCALA_52_SK12
B_R_L_GOT64_LO12 B_R_L_GOT_ABS_0_SK12 *5
B_R_L_GOT64_HI20 B_R_L_GOT_ABS_12_SJ20
B_R_L_GOT64_LO20 B_R_L_GOT_ABS_32_SJ20
B_R_L_GOT64_HI12 B_R_L_GOT_ABS_52_SK12
B_R_L_TLS_LE_LO12 B_R_L_TLS_LE_ABS_0_SK12
B_R_L_TLS_LE_HI20 B_R_L_TLS_LE_ABS_12_SJ20
B_R_L_TLS_LE64_LO20 B_R_L_TLS_LE_ABS_32_SJ20
B_R_L_TLS_LE64_HI12 B_R_L_TLS_LE_ABS_52_SK12
B_R_L_TLS_IE_PC_LO12 B_R_L_TLS_IE_PCALA_0_SK12
B_R_L_TLS_IE_PC_HI20 B_R_L_TLS_IE_PCALA_12_SJ20
B_R_L_TLS_IE64_PC_LO20 B_R_L_TLS_IE_PCALA_32_SJ20
B_R_L_TLS_IE64_PC_HI12 B_R_L_TLS_IE_PCALA_52_SK12
B_R_L_TLS_IE64_LO12 B_R_L_TLS_IE_ABS_0_SK12
B_R_L_TLS_IE64_HI20 B_R_L_TLS_IE_ABS_12_SJ20
B_R_L_TLS_IE64_LO20 B_R_L_TLS_IE_ABS_32_SJ20
B_R_L_TLS_IE64_HI12 B_R_L_TLS_IE_ABS_52_SK12
B_R_L_TLS_LD_PC_HI20 B_R_L_TLS_LD_PCALA_12_SJ20 *6
B_R_L_TLS_LD64_HI20 B_R_L_TLS_LD_ABS_12_SJ20
B_R_L_TLS_GD_PC_HI20 B_R_L_TLS_GD_PCALA_12_SJ20
B_R_L_TLS_GD64_HI20 B_R_L_TLS_GD_ABS_12_SJ20
*1 PCREL is explicitly called out. As you can see, every reloc type
looks like "<purpose>_<starting bit position>_<destination slot>".
*2 I've reordered the types so that in each group of 4 reloc types it's
always from LSB to MSB. And while I don't know what "PCALA" means, I've
kept them all, and distinct from "PCREL" because the jumps and PCADDU12I
don't clear the lowest 12 bits of destination, thus immediates for use
with PCALAU12I needs to be differentiated.
*3 With the starting bit position explicit called out, no "64"
distinction needs to be made.
*4 This (and others) actually uses the PCALAU12I, so should be named
accordingly.
*5 This (and others) seems like an absolute reloc (it uses the same
LU12I.W + xxx + LU32I.D + LU52I.D sequence), so ABS is added to name.
*6 I can't immediately make sense of the last 4 reloc types, but I've
renamed these too. I would have to dig deeper for understanding the
expected use case.
And I hope with this proposal, the (bikeshedding) discussion could be
well-founded and constructive.
> + BFD_RELOC_LARCH_RELAX,
I see this is just being reserved but without any actual behavior
specified. Is it better to just leave it out for now?
<snip>
>
> /* Processor specific flags for the ELF header e_flags field. */
> @@ -102,9 +238,9 @@ END_RELOC_NUMBERS (R_LARCH_count)
> #define EF_LOONGARCH_ABI_ILP32_SINGLE_FLOAT 0x6
> #define EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT 0x7
>
> -#define EF_LOONGARCH_ABI_MASK 0x7
> -#define EF_LOONGARCH_ABI_ILP32_MASK 0x4
> -#define EF_LOONGARCH_ABI_FLOAT_MASK 0x3
> +#define EF_LOONGARCH_ABI_MASK 0x7
> +#define EF_LOONGARCH_ABI_ILP32_MASK 0x4
> +#define EF_LOONGARCH_ABI_FLOAT_MASK 0x3
> #define EF_LOONGARCH_ABI_SOFT_FLOAT_MASK 0x1
> #define EF_LOONGARCH_ABI_SINGLE_FLOAT_MASK 0x2
> #define EF_LOONGARCH_ABI_DOUBLE_FLOAT_MASK 0x3
This hunk looks like pure cosmetic change, could this be split out (and
get committed very quickly unlike the other major changes)?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-18 10:06 ` [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types WANG Xuerui
@ 2022-07-18 11:33 ` Xi Ruoyao
2022-07-18 12:11 ` WANG Xuerui
2022-07-19 7:32 ` liuzhensong
2022-07-20 2:42 ` liuzhensong
2 siblings, 1 reply; 24+ messages in thread
From: Xi Ruoyao @ 2022-07-18 11:33 UTC (permalink / raw)
To: WANG Xuerui, liuzhensong, binutils; +Cc: xuchenghua, mengqinggang, Fangrui Song
On Mon, 2022-07-18 at 18:06 +0800, WANG Xuerui wrote:
> (Adding Ruoyao and MaskRay to CC, who might be interested in this
> development as well, as it concerns the linker implementation.)
I've already subscribed binutils@sourceware.org in order not to be
passed by.
> I think I've voiced my concerns over the naming of these ops multiple
> times already; the primary comment ([1]; in English) was posted back in
> May but no one in your team responded.
>
> Reproducing the content (and adjusting a little) here:
>
>
> Overall in a good direction (and IMHO the direction everyone should have
> taken in the first place), thanks!
>
Yes, we've been paying additional costs using those "stack based
relocation". I'd like to know why they were proposed in first place?
(Not accusing anyone, just my curiosity: AFAIK no other targets ever
used such a stack for relocation.)
/* snip */
> FYI, I did make a list of my suggested names for these reloc types
> ("BFD_RELOC_LARCH_" abbreviated to "B_R_L_"):
>
> Original name Suggested name
> ------------- --------------
> B_R_L_B16 B_R_L_PCREL_SK16 *1
> B_R_L_B21 B_R_L_PCREL_SD5K16
> B_R_L_B26 B_R_L_PCREL_SD10K16
> B_R_L_ABS_LO12 B_R_L_ABS_0_SK12
> B_R_L_ABS_HI20 B_R_L_ABS_12_SJ20
> B_R_L_ABS64_LO20 B_R_L_ABS_32_SJ20
> B_R_L_ABS64_HI12 B_R_L_ABS_52_SK12
> B_R_L_PCALA_LO12 B_R_L_PCALA_0_SK12 *2
> B_R_L_PCALA_HI20 B_R_L_PCALA_12_SJ20
> B_R_L_PCALA64_LO20 B_R_L_PCALA_32_SJ20 *3
> B_R_L_PCALA64_HI12 B_R_L_PCALA_52_SK12
> B_R_L_GOT_PC_LO12 B_R_L_GOT_PCALA_0_SK12 *4
> B_R_L_GOT_PC_HI20 B_R_L_GOT_PCALA_12_SJ20
> B_R_L_GOT64_PC_LO20 B_R_L_GOT_PCALA_32_SJ20
> B_R_L_GOT64_PC_HI12 B_R_L_GOT_PCALA_52_SK12
> B_R_L_GOT64_LO12 B_R_L_GOT_ABS_0_SK12 *5
> B_R_L_GOT64_HI20 B_R_L_GOT_ABS_12_SJ20
> B_R_L_GOT64_LO20 B_R_L_GOT_ABS_32_SJ20
> B_R_L_GOT64_HI12 B_R_L_GOT_ABS_52_SK12
> B_R_L_TLS_LE_LO12 B_R_L_TLS_LE_ABS_0_SK12
> B_R_L_TLS_LE_HI20 B_R_L_TLS_LE_ABS_12_SJ20
> B_R_L_TLS_LE64_LO20 B_R_L_TLS_LE_ABS_32_SJ20
> B_R_L_TLS_LE64_HI12 B_R_L_TLS_LE_ABS_52_SK12
> B_R_L_TLS_IE_PC_LO12 B_R_L_TLS_IE_PCALA_0_SK12
> B_R_L_TLS_IE_PC_HI20 B_R_L_TLS_IE_PCALA_12_SJ20
> B_R_L_TLS_IE64_PC_LO20 B_R_L_TLS_IE_PCALA_32_SJ20
> B_R_L_TLS_IE64_PC_HI12 B_R_L_TLS_IE_PCALA_52_SK12
> B_R_L_TLS_IE64_LO12 B_R_L_TLS_IE_ABS_0_SK12
> B_R_L_TLS_IE64_HI20 B_R_L_TLS_IE_ABS_12_SJ20
> B_R_L_TLS_IE64_LO20 B_R_L_TLS_IE_ABS_32_SJ20
> B_R_L_TLS_IE64_HI12 B_R_L_TLS_IE_ABS_52_SK12
> B_R_L_TLS_LD_PC_HI20 B_R_L_TLS_LD_PCALA_12_SJ20 *6
> B_R_L_TLS_LD64_HI20 B_R_L_TLS_LD_ABS_12_SJ20
> B_R_L_TLS_GD_PC_HI20 B_R_L_TLS_GD_PCALA_12_SJ20
> B_R_L_TLS_GD64_HI20 B_R_L_TLS_GD_ABS_12_SJ20
It's overall better, but those "J, K" etc are cryptic IMHO. And for
"B_R_L_B16" I think "B_R_L_PCREL_SK16" fails to express that the offset
should be shifted right by 2, so I'd keep B_R_L_B16 (and similarly,
B_R_L_B21 and B_R_L_B26) like the PCALA case.
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 4/5 v1] LoongArch: Move ifunc info to rela.dyn from rela.plt.
2022-07-18 8:43 ` [PATCH 4/5 v1] LoongArch: Move ifunc info to rela.dyn from rela.plt liuzhensong
@ 2022-07-18 11:45 ` Xi Ruoyao
2022-07-18 16:27 ` Xi Ruoyao
1 sibling, 0 replies; 24+ messages in thread
From: Xi Ruoyao @ 2022-07-18 11:45 UTC (permalink / raw)
To: liuzhensong, binutils; +Cc: xuchenghua, mengqinggang, WANG Xuerui
On Mon, 2022-07-18 at 16:43 +0800, liuzhensong wrote:
> Delete R_LARCH_IRELATIVE from dynamic loader (glibc ld.so) when
> loading lazy function (rela.plt section).
>
> In dynamic programes, move ifunc dynamic relocate info to section
> srelgot from srelplt.
>
> bfd/
> elfnn-loongarch.c
> ---
> bfd/elfnn-loongarch.c | 322 ++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 310 insertions(+), 12 deletions(-)
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index 4eeaeb44eff..5bb7596e5d0 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -1207,6 +1207,259 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
> return true;
> }
>
> +/* Based function _bfd_elf_allocate_ifunc_dyn_relocs.
"A modified version of _bfd_elf_allocate_ifunc_dyn_relocs."
> + For local def and ref ifunc,
> + dynamic relocations are stored in
> + 1. rel[a].irelifunc section in PIC object.
> + 2. rel[a].srelgot section in dynamic executable.
> + 3. rel[a].irelplt section in static executable.
For entire patch, I think it's better to remove those "[]" around "a":
for LoongArch we always use .rela.*, not .rel.* .
> + Change ifunc dynamic info from srelplt to srelgot.
> + In loader, remove R_LARCH_IRELACTIVE from rela lazy in ld.so. */
"Unlike _bfd_elf_allocate_ifunc_dyn_relocs, .rela.srelgot is used
instead of .rela.srelplt. Glibc ELF loader will not support
R_LARCH_IRELATIVE relocation in .rela.plt."
My English is not good either, but the origin comment is obviously some
Chinglish. Xuerui: can you help to reword the comments in this series?
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-18 11:33 ` Xi Ruoyao
@ 2022-07-18 12:11 ` WANG Xuerui
2022-07-18 12:18 ` WANG Xuerui
` (2 more replies)
0 siblings, 3 replies; 24+ messages in thread
From: WANG Xuerui @ 2022-07-18 12:11 UTC (permalink / raw)
To: Xi Ruoyao, WANG Xuerui, liuzhensong, binutils
Cc: xuchenghua, mengqinggang, Fangrui Song
On 2022/7/18 19:33, Xi Ruoyao wrote:
> On Mon, 2022-07-18 at 18:06 +0800, WANG Xuerui wrote:
>> (Adding Ruoyao and MaskRay to CC, who might be interested in this
>> development as well, as it concerns the linker implementation.)
> I've already subscribed binutils@sourceware.org in order not to be
> passed by.
>
>> I think I've voiced my concerns over the naming of these ops multiple
>> times already; the primary comment ([1]; in English) was posted back in
>> May but no one in your team responded.
>>
>> Reproducing the content (and adjusting a little) here:
>>
>>
>> Overall in a good direction (and IMHO the direction everyone should have
>> taken in the first place), thanks!
>>
> Yes, we've been paying additional costs using those "stack based
> relocation". I'd like to know why they were proposed in first place?
> (Not accusing anyone, just my curiosity: AFAIK no other targets ever
> used such a stack for relocation.)
As previously pointed out on this list, rx and rl78 both use stack-based
relocs. (Both come from Renesas, so I do think it's delibrate design
decision, but of course the original Renesas justification is most
probably buried in history.) I explained this in
https://github.com/loongson/binutils-gdb/issues/134 before.
>
> /* snip */
>
>
>> FYI, I did make a list of my suggested names for these reloc types
>> ("BFD_RELOC_LARCH_" abbreviated to "B_R_L_"):
>>
>> Original name Suggested name
>> ------------- --------------
>> B_R_L_B16 B_R_L_PCREL_SK16 *1
>> B_R_L_B21 B_R_L_PCREL_SD5K16
>> B_R_L_B26 B_R_L_PCREL_SD10K16
>> B_R_L_ABS_LO12 B_R_L_ABS_0_SK12
>> B_R_L_ABS_HI20 B_R_L_ABS_12_SJ20
>> B_R_L_ABS64_LO20 B_R_L_ABS_32_SJ20
>> B_R_L_ABS64_HI12 B_R_L_ABS_52_SK12
>> B_R_L_PCALA_LO12 B_R_L_PCALA_0_SK12 *2
>> B_R_L_PCALA_HI20 B_R_L_PCALA_12_SJ20
>> B_R_L_PCALA64_LO20 B_R_L_PCALA_32_SJ20 *3
>> B_R_L_PCALA64_HI12 B_R_L_PCALA_52_SK12
>> B_R_L_GOT_PC_LO12 B_R_L_GOT_PCALA_0_SK12 *4
>> B_R_L_GOT_PC_HI20 B_R_L_GOT_PCALA_12_SJ20
>> B_R_L_GOT64_PC_LO20 B_R_L_GOT_PCALA_32_SJ20
>> B_R_L_GOT64_PC_HI12 B_R_L_GOT_PCALA_52_SK12
>> B_R_L_GOT64_LO12 B_R_L_GOT_ABS_0_SK12 *5
>> B_R_L_GOT64_HI20 B_R_L_GOT_ABS_12_SJ20
>> B_R_L_GOT64_LO20 B_R_L_GOT_ABS_32_SJ20
>> B_R_L_GOT64_HI12 B_R_L_GOT_ABS_52_SK12
>> B_R_L_TLS_LE_LO12 B_R_L_TLS_LE_ABS_0_SK12
>> B_R_L_TLS_LE_HI20 B_R_L_TLS_LE_ABS_12_SJ20
>> B_R_L_TLS_LE64_LO20 B_R_L_TLS_LE_ABS_32_SJ20
>> B_R_L_TLS_LE64_HI12 B_R_L_TLS_LE_ABS_52_SK12
>> B_R_L_TLS_IE_PC_LO12 B_R_L_TLS_IE_PCALA_0_SK12
>> B_R_L_TLS_IE_PC_HI20 B_R_L_TLS_IE_PCALA_12_SJ20
>> B_R_L_TLS_IE64_PC_LO20 B_R_L_TLS_IE_PCALA_32_SJ20
>> B_R_L_TLS_IE64_PC_HI12 B_R_L_TLS_IE_PCALA_52_SK12
>> B_R_L_TLS_IE64_LO12 B_R_L_TLS_IE_ABS_0_SK12
>> B_R_L_TLS_IE64_HI20 B_R_L_TLS_IE_ABS_12_SJ20
>> B_R_L_TLS_IE64_LO20 B_R_L_TLS_IE_ABS_32_SJ20
>> B_R_L_TLS_IE64_HI12 B_R_L_TLS_IE_ABS_52_SK12
>> B_R_L_TLS_LD_PC_HI20 B_R_L_TLS_LD_PCALA_12_SJ20 *6
>> B_R_L_TLS_LD64_HI20 B_R_L_TLS_LD_ABS_12_SJ20
>> B_R_L_TLS_GD_PC_HI20 B_R_L_TLS_GD_PCALA_12_SJ20
>> B_R_L_TLS_GD64_HI20 B_R_L_TLS_GD_ABS_12_SJ20
> It's overall better, but those "J, K" etc are cryptic IMHO. And for
> "B_R_L_B16" I think "B_R_L_PCREL_SK16" fails to express that the offset
> should be shifted right by 2, so I'd keep B_R_L_B16 (and similarly,
> B_R_L_B21 and B_R_L_B26) like the PCALA case.
>
The slot names come from
https://github.com/loongson/LoongArch-Documentation/pull/56 (to
non-Chinese speakers: English translation still TODO, but hopefully at
least the ABNF and the few tables should be intelligible even without
translation).
As for the PCREL and implicit shifts, maybe a planned extension of the
slot syntax could help. I plan to submit an Assembly Language Convention
after the Instruction Format Convention gets reviewed and merged, and
with this new convention such an extension is necessary anyway for
accommodating the current assembly syntax as described by the ISA
manual, able to express the <<2's and +1's for the PC-manipulating and
ALSL insns.
For example, let's say the extension works like this: ordinary slot
syntax, plus "p", plus an postprocess operator, with "s\d+" for "imm
slot = assembly operand >> N", and "p\d+" for "imm slot = assembly
operand + N". Then we could say "B_R_L_PCREL_SK16PS2" and have all the
niceties. (In an ideal world, the LoongArch opcodes implementation
should be modified to use this convention too, so for example it will be
something like "DJSk16ps2" for JIRL, "JDSk16ps2" for BLT (notice the
reversed operand order) and "DJKUa2pp1" for ALSL insns.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-18 12:11 ` WANG Xuerui
@ 2022-07-18 12:18 ` WANG Xuerui
2022-07-19 3:57 ` Fangrui Song
2022-07-20 2:07 ` liuzhensong
2 siblings, 0 replies; 24+ messages in thread
From: WANG Xuerui @ 2022-07-18 12:18 UTC (permalink / raw)
To: WANG Xuerui, Xi Ruoyao, liuzhensong, binutils
Cc: xuchenghua, mengqinggang, Fangrui Song
On 2022/7/18 20:11, WANG Xuerui wrote:
> For example, let's say the extension works like this: ordinary slot
> syntax, plus "p", plus an postprocess operator, with "s\d+" for "imm
> slot = assembly operand >> N", and "p\d+" for "imm slot = assembly
> operand + N".
Actually it's "imm slot = assembly operand - N" for the proposed "p\d+".
It doesn't matter that much though, because ALSLs don't take part in
relocation, it was just a side mention.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 4/5 v1] LoongArch: Move ifunc info to rela.dyn from rela.plt.
2022-07-18 8:43 ` [PATCH 4/5 v1] LoongArch: Move ifunc info to rela.dyn from rela.plt liuzhensong
2022-07-18 11:45 ` Xi Ruoyao
@ 2022-07-18 16:27 ` Xi Ruoyao
2022-07-19 7:26 ` liuzhensong
1 sibling, 1 reply; 24+ messages in thread
From: Xi Ruoyao @ 2022-07-18 16:27 UTC (permalink / raw)
To: liuzhensong, binutils; +Cc: xuchenghua, mengqinggang, WANG Xuerui
On Mon, 2022-07-18 at 16:43 +0800, liuzhensong wrote:
> Delete R_LARCH_IRELATIVE from dynamic loader (glibc ld.so) when
> loading lazy function (rela.plt section).
>
> In dynamic programes, move ifunc dynamic relocate info to section
> srelgot from srelplt.
The main point of this change is allowing us to enable ifunc support for
Glibc, right?
But have you tested building Glibc using a ld with this series applied?
It does not work well for me:
FAIL: elf/ifuncmain1
FAIL: elf/ifuncmain1pic
FAIL: elf/ifuncmain1pie
FAIL: elf/ifuncmain1staticpic
FAIL: elf/ifuncmain1staticpie
FAIL: elf/ifuncmain1vis
FAIL: elf/ifuncmain1vispic
FAIL: elf/ifuncmain1vispie
FAIL: elf/ifuncmain3
FAIL: elf/ifuncmain4
FAIL: elf/ifuncmain5staticpic
FAIL: elf/ifuncmain7
FAIL: elf/ifuncmain7pic
FAIL: elf/ifuncmain7pie
Note that Binutils test suite is far from complete. For example, the
ifunc handling for LoongArch target in master branch (with or w/o this
patch) can pass all ld tests, but it just blows up with a simple test
case:
$ cat c.s
.global ifunc
.type ifunc, @gnu_indirect_function
.set ifunc, resolver
resolver:
la.local $a0, impl
jr $ra
impl:
li.w $a0, 42
jr $ra
.data
.global x
.type x, @object
x:
.dword ifunc
$ cc c.s -shared
collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core dumped
compilation terminated.
So I think you'll at least need to build kernel/glibc/gcc using a ld
with your patches to make sure it works correctly.
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-18 12:11 ` WANG Xuerui
2022-07-18 12:18 ` WANG Xuerui
@ 2022-07-19 3:57 ` Fangrui Song
2022-07-20 7:47 ` liuzhensong
2022-07-20 2:07 ` liuzhensong
2 siblings, 1 reply; 24+ messages in thread
From: Fangrui Song @ 2022-07-19 3:57 UTC (permalink / raw)
To: WANG Xuerui; +Cc: Xi Ruoyao, liuzhensong, binutils, xuchenghua, mengqinggang
On 2022-07-18, WANG Xuerui wrote:
>On 2022/7/18 19:33, Xi Ruoyao wrote:
>>On Mon, 2022-07-18 at 18:06 +0800, WANG Xuerui wrote:
>>>(Adding Ruoyao and MaskRay to CC, who might be interested in this
>>>development as well, as it concerns the linker implementation.)
>>I've already subscribed binutils@sourceware.org in order not to be
>>passed by.
I am subscribed, too. Direct CC helps me find the discussions:)
>>>I think I've voiced my concerns over the naming of these ops multiple
>>>times already; the primary comment ([1]; in English) was posted back in
>>>May but no one in your team responded.
>>>
>>>Reproducing the content (and adjusting a little) here:
>>>
>>>
>>>Overall in a good direction (and IMHO the direction everyone should have
>>>taken in the first place), thanks!
>>>
>>Yes, we've been paying additional costs using those "stack based
>>relocation". I'd like to know why they were proposed in first place?
>>(Not accusing anyone, just my curiosity: AFAIK no other targets ever
>>used such a stack for relocation.)
>As previously pointed out on this list, rx and rl78 both use
>stack-based relocs. (Both come from Renesas, so I do think it's
>delibrate design decision, but of course the original Renesas
>justification is most probably buried in history.) I explained this in
>https://github.com/loongson/binutils-gdb/issues/134 before.
Stack machines aren't really suitable for ELF relocations.
Each relocation takes sizeof(Elf64_Rela) = 24 byte, higher than older
object file formats.
ELF32 allows 256 relocation types. There aren't too many to waste.
>>
>>/* snip */
>>
>>
>>>FYI, I did make a list of my suggested names for these reloc types
>>>("BFD_RELOC_LARCH_" abbreviated to "B_R_L_"):
>>>
>>>Original name Suggested name
>>>------------- --------------
>>>B_R_L_B16 B_R_L_PCREL_SK16 *1
>>>B_R_L_B21 B_R_L_PCREL_SD5K16
>>>B_R_L_B26 B_R_L_PCREL_SD10K16
>>>B_R_L_ABS_LO12 B_R_L_ABS_0_SK12
>>>B_R_L_ABS_HI20 B_R_L_ABS_12_SJ20
>>>B_R_L_ABS64_LO20 B_R_L_ABS_32_SJ20
>>>B_R_L_ABS64_HI12 B_R_L_ABS_52_SK12
aarch64 calls these G0/G1/G2/G3 while ppc calls these LO/HI/HIGHER/HIGHEST.
A name mentioning the offset and the length looks good to me, too.
A too-long name may have problems in the default (non-wide) output of
readelf -r.
>>>B_R_L_PCALA_LO12 B_R_L_PCALA_0_SK12 *2
>>>B_R_L_PCALA_HI20 B_R_L_PCALA_12_SJ20
>>>B_R_L_PCALA64_LO20 B_R_L_PCALA_32_SJ20 *3
>>>B_R_L_PCALA64_HI12 B_R_L_PCALA_52_SK12
>>>B_R_L_GOT_PC_LO12 B_R_L_GOT_PCALA_0_SK12 *4
>>>B_R_L_GOT_PC_HI20 B_R_L_GOT_PCALA_12_SJ20
>>>B_R_L_GOT64_PC_LO20 B_R_L_GOT_PCALA_32_SJ20
>>>B_R_L_GOT64_PC_HI12 B_R_L_GOT_PCALA_52_SK12
>>>B_R_L_GOT64_LO12 B_R_L_GOT_ABS_0_SK12 *5
>>>B_R_L_GOT64_HI20 B_R_L_GOT_ABS_12_SJ20
>>>B_R_L_GOT64_LO20 B_R_L_GOT_ABS_32_SJ20
>>>B_R_L_GOT64_HI12 B_R_L_GOT_ABS_52_SK12
>>>B_R_L_TLS_LE_LO12 B_R_L_TLS_LE_ABS_0_SK12
>>>B_R_L_TLS_LE_HI20 B_R_L_TLS_LE_ABS_12_SJ20
>>>B_R_L_TLS_LE64_LO20 B_R_L_TLS_LE_ABS_32_SJ20
>>>B_R_L_TLS_LE64_HI12 B_R_L_TLS_LE_ABS_52_SK12
>>>B_R_L_TLS_IE_PC_LO12 B_R_L_TLS_IE_PCALA_0_SK12
>>>B_R_L_TLS_IE_PC_HI20 B_R_L_TLS_IE_PCALA_12_SJ20
>>>B_R_L_TLS_IE64_PC_LO20 B_R_L_TLS_IE_PCALA_32_SJ20
>>>B_R_L_TLS_IE64_PC_HI12 B_R_L_TLS_IE_PCALA_52_SK12
>>>B_R_L_TLS_IE64_LO12 B_R_L_TLS_IE_ABS_0_SK12
>>>B_R_L_TLS_IE64_HI20 B_R_L_TLS_IE_ABS_12_SJ20
>>>B_R_L_TLS_IE64_LO20 B_R_L_TLS_IE_ABS_32_SJ20
>>>B_R_L_TLS_IE64_HI12 B_R_L_TLS_IE_ABS_52_SK12
>>>B_R_L_TLS_LD_PC_HI20 B_R_L_TLS_LD_PCALA_12_SJ20 *6
>>>B_R_L_TLS_LD64_HI20 B_R_L_TLS_LD_ABS_12_SJ20
>>>B_R_L_TLS_GD_PC_HI20 B_R_L_TLS_GD_PCALA_12_SJ20
>>>B_R_L_TLS_GD64_HI20 B_R_L_TLS_GD_ABS_12_SJ20
aarch64 relocation types are well named. It's obvious what suppress
overflow checking.
For LO12, I expect that there are two variants: one with overflow check,
the other without.
>>It's overall better, but those "J, K" etc are cryptic IMHO. And for
>>"B_R_L_B16" I think "B_R_L_PCREL_SK16" fails to express that the offset
>>should be shifted right by 2, so I'd keep B_R_L_B16 (and similarly,
>>B_R_L_B21 and B_R_L_B26) like the PCALA case.
>>
>The slot names come from
>https://github.com/loongson/LoongArch-Documentation/pull/56 (to
>non-Chinese speakers: English translation still TODO, but hopefully at
>least the ABNF and the few tables should be intelligible even without
>translation).
>
>As for the PCREL and implicit shifts, maybe a planned extension of the
>slot syntax could help. I plan to submit an Assembly Language
>Convention after the Instruction Format Convention gets reviewed and
>merged, and with this new convention such an extension is necessary
>anyway for accommodating the current assembly syntax as described by
>the ISA manual, able to express the <<2's and +1's for the
>PC-manipulating and ALSL insns.
>
>For example, let's say the extension works like this: ordinary slot
>syntax, plus "p", plus an postprocess operator, with "s\d+" for "imm
>slot = assembly operand >> N", and "p\d+" for "imm slot = assembly
>operand + N". Then we could say "B_R_L_PCREL_SK16PS2" and have all the
>niceties. (In an ideal world, the LoongArch opcodes implementation
>should be modified to use this convention too, so for example it will
>be something like "DJSk16ps2" for JIRL, "JDSk16ps2" for BLT (notice
>the reversed operand order) and "DJKUa2pp1" for ALSL insns.
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-18 8:43 [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types liuzhensong
` (4 preceding siblings ...)
2022-07-18 10:06 ` [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types WANG Xuerui
@ 2022-07-19 4:29 ` Xi Ruoyao
2022-07-19 5:40 ` Xi Ruoyao
5 siblings, 1 reply; 24+ messages in thread
From: Xi Ruoyao @ 2022-07-19 4:29 UTC (permalink / raw)
To: liuzhensong, binutils; +Cc: xuchenghua, mengqinggang, WANG Xuerui
On Mon, 2022-07-18 at 16:43 +0800, liuzhensong wrote:
> @@ -2427,7 +2453,7 @@ loongarch_elf_relocate_section (bfd *output_bfd,
> struct bfd_link_info *info,
>
> if (h != NULL)
> {
> - off = h->got.offset;
> + off = h->got.offset & (~1);
>
> if (off == MINUS_ONE
> && h->type != STT_GNU_IFUNC)
> @@ -2455,79 +2481,76 @@ loongarch_elf_relocate_section (bfd
> *output_bfd, struct bfd_link_info *info,
This cannot be correct: after "off = h->got.offset & (~1)", how could
"off == MINUS_ONE" be true?
Either you calculated "off" wrong, or you should remove the dead code.
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-19 4:29 ` Xi Ruoyao
@ 2022-07-19 5:40 ` Xi Ruoyao
2022-07-19 6:31 ` 刘振松
0 siblings, 1 reply; 24+ messages in thread
From: Xi Ruoyao @ 2022-07-19 5:40 UTC (permalink / raw)
To: liuzhensong, binutils; +Cc: xuchenghua, mengqinggang, WANG Xuerui
On Tue, 2022-07-19 at 12:29 +0800, Xi Ruoyao via Binutils wrote:
> On Mon, 2022-07-18 at 16:43 +0800, liuzhensong wrote:
> > @@ -2427,7 +2453,7 @@ loongarch_elf_relocate_section (bfd
> > *output_bfd,
> > struct bfd_link_info *info,
> >
> > if (h != NULL)
> > {
> > - off = h->got.offset;
> > + off = h->got.offset & (~1);
> >
> > if (off == MINUS_ONE
> > && h->type != STT_GNU_IFUNC)
> > @@ -2455,79 +2481,76 @@ loongarch_elf_relocate_section (bfd
> > *output_bfd, struct bfd_link_info *info,
>
> This cannot be correct: after "off = h->got.offset & (~1)", how could
> "off == MINUS_ONE" be true?
>
> Either you calculated "off" wrong, or you should remove the dead code.
I guess you need the following changes. With those changes Glibc ifunc
tests passed:
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 44b8d6dca9b..4d22ba037c8 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -2730,7 +2730,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{
off = h->got.offset & (~1);
- if (off == MINUS_ONE
+ if (h->got.offset == MINUS_ONE
&& h->type != STT_GNU_IFUNC)
{
fatal = (loongarch_reloc_is_fatal
@@ -2742,7 +2742,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* Hidden symbol not has .got entry, only .got.plt entry
so gprel is (plt - got). */
- if (off == MINUS_ONE
+ if (h->got.offset == MINUS_ONE
&& h->type == STT_GNU_IFUNC)
{
if (h->plt.offset == (bfd_vma) -1)
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-19 5:40 ` Xi Ruoyao
@ 2022-07-19 6:31 ` 刘振松
2022-07-19 6:34 ` Xi Ruoyao
0 siblings, 1 reply; 24+ messages in thread
From: 刘振松 @ 2022-07-19 6:31 UTC (permalink / raw)
To: Xi Ruoyao; +Cc: binutils, xuchenghua, mengqinggang, WANG Xuerui
> -----原始邮件-----
> 发件人: "Xi Ruoyao" <xry111@xry111.site>
> 发送时间: 2022-07-19 13:40:02 (星期二)
> 收件人: liuzhensong <liuzhensong@loongson.cn>, binutils@sourceware.org
> 抄送: xuchenghua@loongson.cn, mengqinggang@loongson.cn, "WANG Xuerui" <i.swmail@xen0n.name>
> 主题: Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
>
> On Tue, 2022-07-19 at 12:29 +0800, Xi Ruoyao via Binutils wrote:
> > On Mon, 2022-07-18 at 16:43 +0800, liuzhensong wrote:
> > > @@ -2427,7 +2453,7 @@ loongarch_elf_relocate_section (bfd
> > > *output_bfd,
> > > struct bfd_link_info *info,
> > >
> > > if (h != NULL)
> > > {
> > > - off = h->got.offset;
> > > + off = h->got.offset & (~1);
> > >
> > > if (off == MINUS_ONE
> > > && h->type != STT_GNU_IFUNC)
> > > @@ -2455,79 +2481,76 @@ loongarch_elf_relocate_section (bfd
> > > *output_bfd, struct bfd_link_info *info,
> >
> > This cannot be correct: after "off = h->got.offset & (~1)", how could
> > "off == MINUS_ONE" be true?
> >
> > Either you calculated "off" wrong, or you should remove the dead code.
>
> I guess you need the following changes. With those changes Glibc ifunc
> tests passed:
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index 44b8d6dca9b..4d22ba037c8 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -2730,7 +2730,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
> {
> off = h->got.offset & (~1);
>
> - if (off == MINUS_ONE
> + if (h->got.offset == MINUS_ONE
> && h->type != STT_GNU_IFUNC)
> {
> fatal = (loongarch_reloc_is_fatal
> @@ -2742,7 +2742,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>
> /* Hidden symbol not has .got entry, only .got.plt entry
> so gprel is (plt - got). */
> - if (off == MINUS_ONE
> + if (h->got.offset == MINUS_ONE
> && h->type == STT_GNU_IFUNC)
> {
> if (h->plt.offset == (bfd_vma) -1)
>
> --
> Xi Ruoyao <xry111@xry111.site>
> School of Aerospace Science and Technology, Xidian University
Thanks for reviews.
Your modification is correct, this code valid for R_LARCH_SOP_PUSH_GPREL.
I have tested glibc testcases, there is no failed testcase about ifunc, does your environment generate new relocations?
Results of glibc with test args "make check subdirs=elf".
UNSUPPORTED: elf/tst-env-setuid
UNSUPPORTED: elf/tst-env-setuid-tunables
XPASS: elf/tst-protected1a
XPASS: elf/tst-protected1b
UNSUPPORTED: elf/tst-valgrind-smoke
Summary of test results:
312 PASS
3 UNSUPPORTED
2 XPASS</xry111@xry111.site></i.swmail@xen0n.name></liuzhensong@loongson.cn></xry111@xry111.site>
本邮件及其附件含有龙芯中科的商业秘密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制或散发)本邮件及其附件中的信息。如果您错收本邮件,请您立即电话或邮件通知发件人并删除本邮件。
This email and its attachments contain confidential information from Loongson Technology , which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this email in error, please notify the sender by phone or email immediately and delete it.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-19 6:31 ` 刘振松
@ 2022-07-19 6:34 ` Xi Ruoyao
0 siblings, 0 replies; 24+ messages in thread
From: Xi Ruoyao @ 2022-07-19 6:34 UTC (permalink / raw)
To: 刘振松; +Cc: binutils, xuchenghua, mengqinggang, WANG Xuerui
On Tue, 2022-07-19 at 14:31 +0800, 刘振松 wrote:
> Your modification is correct, this code valid for
> R_LARCH_SOP_PUSH_GPREL.
> I have tested glibc testcases, there is no failed testcase about
> ifunc, does your environment generate new relocations?
I guess it's because I only installed new ld (make install-ld), without
new as. So my as still generates R_LARCH_SOP_PUSH_GPREL.
> Results of glibc with test args "make check subdirs=elf".
> UNSUPPORTED: elf/tst-env-setuid
> UNSUPPORTED: elf/tst-env-setuid-tunables
> XPASS: elf/tst-protected1a
> XPASS: elf/tst-protected1b
> UNSUPPORTED: elf/tst-valgrind-smoke
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 4/5 v1] LoongArch: Move ifunc info to rela.dyn from rela.plt.
2022-07-18 16:27 ` Xi Ruoyao
@ 2022-07-19 7:26 ` liuzhensong
0 siblings, 0 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-19 7:26 UTC (permalink / raw)
To: Xi Ruoyao, binutils; +Cc: xuchenghua, mengqinggang, WANG Xuerui
在 2022/7/19 上午12:27, Xi Ruoyao 写道:
> On Mon, 2022-07-18 at 16:43 +0800, liuzhensong wrote:
>> Delete R_LARCH_IRELATIVE from dynamic loader (glibc ld.so) when
>> loading lazy function (rela.plt section).
>>
>> In dynamic programes, move ifunc dynamic relocate info to section
>> srelgot from srelplt.
> The main point of this change is allowing us to enable ifunc support for
> Glibc, right?
>
> But have you tested building Glibc using a ld with this series applied?
> It does not work well for me:
>
> FAIL: elf/ifuncmain1
> FAIL: elf/ifuncmain1pic
> FAIL: elf/ifuncmain1pie
> FAIL: elf/ifuncmain1staticpic
> FAIL: elf/ifuncmain1staticpie
> FAIL: elf/ifuncmain1vis
> FAIL: elf/ifuncmain1vispic
> FAIL: elf/ifuncmain1vispie
> FAIL: elf/ifuncmain3
> FAIL: elf/ifuncmain4
> FAIL: elf/ifuncmain5staticpic
> FAIL: elf/ifuncmain7
> FAIL: elf/ifuncmain7pic
> FAIL: elf/ifuncmain7pie
>
> Note that Binutils test suite is far from complete. For example, the
> ifunc handling for LoongArch target in master branch (with or w/o this
> patch) can pass all ld tests, but it just blows up with a simple test
> case:
>
> $ cat c.s
> .global ifunc
> .type ifunc, @gnu_indirect_function
> .set ifunc, resolver
>
> resolver:
> la.local $a0, impl
> jr $ra
>
> impl:
> li.w $a0, 42
> jr $ra
>
> .data
> .global x
> .type x, @object
> x:
> .dword ifunc
>
> $ cc c.s -shared
> collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core dumped
> compilation terminated.
>
> So I think you'll at least need to build kernel/glibc/gcc using a ld
> with your patches to make sure it works correctly.
This is a bug, will be triggered:
1. a pointer point to a global ifunc,
2. compiling into a shared dynamic library.
We will fix and test this issue soon.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-18 10:06 ` [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types WANG Xuerui
2022-07-18 11:33 ` Xi Ruoyao
@ 2022-07-19 7:32 ` liuzhensong
2022-07-20 2:42 ` liuzhensong
2 siblings, 0 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-19 7:32 UTC (permalink / raw)
To: WANG Xuerui, binutils; +Cc: xuchenghua, mengqinggang, Xi Ruoyao, Fangrui Song
在 2022/7/18 下午6:06, WANG Xuerui 写道:
> (Adding Ruoyao and MaskRay to CC, who might be interested in this
> development as well, as it concerns the linker implementation.)
>
>
> On 2022/7/18 16:43, liuzhensong wrote:
>
>> This is the v1 version of patches to support new relocs for LoongArch.
>>
>> The new reloc types docnments are on:
>> https://github.com/loongson/LoongArch-Documentation/pull/57/files
>>
>> The testsuite status:
>>
>> === binutils Summary ===
>> # of expected passes 241
>> # of unsupported tests 6
>>
>> === gas Summary ===
>> # of expected passes 270
>> # of unsupported tests 7
>>
>> === ld Summary ===
>> # of expected passes 1457
>> # of expected failures 11
>> # of untested testcases 1
>> # of unsupported tests 154
>>
> I assume the content above are the "cover letter".
>
> BTW: you can generate a proper patch series with `git format-patch -vN
> --cover-letter <base>`; I think the mails in this series were manually
> edited by you since the "v1" is wrongly placed (it's usually "[PATCH
> vN NN/NN]").
>
>> Add new reloc types support, the new relocate type
>> definition depends which operation needs of linker.
> "Define new reloc types according to linker needs" could be enough.
>>
>>
>> ---
>> bfd/bfd-in2.h | 36 ++
>> bfd/elfnn-loongarch.c | 1194 ++++++++++++++++++++++------------
>> bfd/elfxx-loongarch.c | 1354 +++++++++++++++++++++++++++++----------
>> bfd/elfxx-loongarch.h | 4 +
>> bfd/libbfd.h | 36 ++
>> bfd/reloc.c | 79 +++
>> include/elf/loongarch.h | 142 +++-
>> 7 files changed, 2095 insertions(+), 750 deletions(-)
>>
>> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
>> index 4e1182e93d4..a71b3e82057 100644
>> --- a/bfd/bfd-in2.h
>> +++ b/bfd/bfd-in2.h
>> @@ -6274,6 +6274,42 @@ assembler and not (currently) written to any
>> object files. */
>> BFD_RELOC_LARCH_SUB24,
>> BFD_RELOC_LARCH_SUB32,
>> BFD_RELOC_LARCH_SUB64,
>> + BFD_RELOC_LARCH_B16,
>> + BFD_RELOC_LARCH_B21,
>> + BFD_RELOC_LARCH_B26,
>> + BFD_RELOC_LARCH_ABS_HI20,
>> + BFD_RELOC_LARCH_ABS_LO12,
>> + BFD_RELOC_LARCH_ABS64_LO20,
>> + BFD_RELOC_LARCH_ABS64_HI12,
>> + BFD_RELOC_LARCH_PCALA_HI20,
>> + BFD_RELOC_LARCH_PCALA_LO12,
>> + BFD_RELOC_LARCH_PCALA64_LO20,
>> + BFD_RELOC_LARCH_PCALA64_HI12,
>> + BFD_RELOC_LARCH_GOT_PC_HI20,
>> + BFD_RELOC_LARCH_GOT_PC_LO12,
>> + BFD_RELOC_LARCH_GOT64_PC_LO20,
>> + BFD_RELOC_LARCH_GOT64_PC_HI12,
>> + BFD_RELOC_LARCH_GOT64_HI20,
>> + BFD_RELOC_LARCH_GOT64_LO12,
>> + BFD_RELOC_LARCH_GOT64_LO20,
>> + BFD_RELOC_LARCH_GOT64_HI12,
>> + BFD_RELOC_LARCH_TLS_LE_HI20,
>> + BFD_RELOC_LARCH_TLS_LE_LO12,
>> + BFD_RELOC_LARCH_TLS_LE64_LO20,
>> + BFD_RELOC_LARCH_TLS_LE64_HI12,
>> + BFD_RELOC_LARCH_TLS_IE_PC_HI20,
>> + BFD_RELOC_LARCH_TLS_IE_PC_LO12,
>> + BFD_RELOC_LARCH_TLS_IE64_PC_LO20,
>> + BFD_RELOC_LARCH_TLS_IE64_PC_HI12,
>> + BFD_RELOC_LARCH_TLS_IE64_HI20,
>> + BFD_RELOC_LARCH_TLS_IE64_LO12,
>> + BFD_RELOC_LARCH_TLS_IE64_LO20,
>> + BFD_RELOC_LARCH_TLS_IE64_HI12,
>> + BFD_RELOC_LARCH_TLS_LD_PC_HI20,
>> + BFD_RELOC_LARCH_TLS_LD64_HI20,
>> + BFD_RELOC_LARCH_TLS_GD_PC_HI20,
>> + BFD_RELOC_LARCH_TLS_GD64_HI20,
>
> I think I've voiced my concerns over the naming of these ops multiple
> times already; the primary comment ([1]; in English) was posted back
> in May but no one in your team responded.
>
> Reproducing the content (and adjusting a little) here:
>
>
> Overall in a good direction (and IMHO the direction everyone should
> have taken in the first place), thanks! A few suggestions though:
>
> Some of the names can be a bit hard to understand, for example
> ABS_LO12, ABS_HI20, ABS64_LO20 and ABS64_HI12; these are ambiguous on
> a first look, do you use the latter two instead of the former for
> 64-bit absolute relocs? (The answer is "no"; you use all 4. The latter
> two actually express the higher 32-bit half.)
>
> After having trained your intuition to work in "the Loongson way",
> you'll then have to mentally add the "lower/higher half" and "width"
> together to get a picture of the bit-field being expressed. It could
> be better to somehow directly show the 0(LO)/12/32/52 inside those names.
>
> Plus, currently it's implied that a particular relocation type is
> somehow bound to a specific instruction, that's being used by the
> reference implementation (binutils) for the type today. This is being
> a bit too specific, and could change, as future instructions emerge
> with similar or identical format. (BTW no one really understand what
> "ALA" means in "PCALA"; the insn is named "PCALAU12I", the "U12I" part
> is similar to "LU12I.W" thus understandable, and PC is obvious, but no
> explanation for "ALA" exists anywhere). It's better to express the
> "destination" not in terms of instruction names or vague
> "LO12/HI20/LO20/HI12" specifiers, but in terms of actual *instruction
> word slots* being filled. This way it's immediately obvious for anyone
> what place in the insn word the reloc is going to write to, without
> having to dig into actual linker code. However, you don't officially
> have a naming scheme for these, so I guess that's why you have to
> invent names (and be different with others & prior work).
>
> I have drafted my scheme back in November 2021, which I posted at [2]
> a while ago; the approach is extremely similar (IMO there's only one
> possible way to implement the more traditional scheme), but my version
> has adopted the operand slot naming scheme of loongarch-opcodes ([3];
> the convention document is edited and posted at [4] for inclusion in
> official LoongArch docs collection) and the more direct LO/12/32/52
> names for bit-field offsets (width is implied by the destination
> slot). Hope this would be useful.
>
>
> Again, I may sound like a bikeshedder, but IMO better names benefit
> everyone in the long term. I for one definitely don't want to see all
> four of "LO12/HI20/LO20/HI12" (they refer to the two 32-bit halves of
> a 64-bit value, not two ways to segment one 32-bit value), nor
> "B16/B21/B26" (which are more different than you might think).
>
> [1]: https://github.com/loongson/LoongArch-Documentation/pull/50
> [2]:
> https://github.com/loongson/binutils-gdb/issues/134#issuecomment-1110510582
> [3]: https://github.com/loongson-community/loongarch-opcodes
> [4]: https://github.com/loongson/LoongArch-Documentation/pull/56
>
>
> FYI, I did make a list of my suggested names for these reloc types
> ("BFD_RELOC_LARCH_" abbreviated to "B_R_L_"):
>
> Original name Suggested name
> ------------- --------------
> B_R_L_B16 B_R_L_PCREL_SK16 *1
> B_R_L_B21 B_R_L_PCREL_SD5K16
> B_R_L_B26 B_R_L_PCREL_SD10K16
> B_R_L_ABS_LO12 B_R_L_ABS_0_SK12
> B_R_L_ABS_HI20 B_R_L_ABS_12_SJ20
> B_R_L_ABS64_LO20 B_R_L_ABS_32_SJ20
> B_R_L_ABS64_HI12 B_R_L_ABS_52_SK12
> B_R_L_PCALA_LO12 B_R_L_PCALA_0_SK12 *2
> B_R_L_PCALA_HI20 B_R_L_PCALA_12_SJ20
> B_R_L_PCALA64_LO20 B_R_L_PCALA_32_SJ20 *3
> B_R_L_PCALA64_HI12 B_R_L_PCALA_52_SK12
> B_R_L_GOT_PC_LO12 B_R_L_GOT_PCALA_0_SK12 *4
> B_R_L_GOT_PC_HI20 B_R_L_GOT_PCALA_12_SJ20
> B_R_L_GOT64_PC_LO20 B_R_L_GOT_PCALA_32_SJ20
> B_R_L_GOT64_PC_HI12 B_R_L_GOT_PCALA_52_SK12
> B_R_L_GOT64_LO12 B_R_L_GOT_ABS_0_SK12 *5
> B_R_L_GOT64_HI20 B_R_L_GOT_ABS_12_SJ20
> B_R_L_GOT64_LO20 B_R_L_GOT_ABS_32_SJ20
> B_R_L_GOT64_HI12 B_R_L_GOT_ABS_52_SK12
> B_R_L_TLS_LE_LO12 B_R_L_TLS_LE_ABS_0_SK12
> B_R_L_TLS_LE_HI20 B_R_L_TLS_LE_ABS_12_SJ20
> B_R_L_TLS_LE64_LO20 B_R_L_TLS_LE_ABS_32_SJ20
> B_R_L_TLS_LE64_HI12 B_R_L_TLS_LE_ABS_52_SK12
> B_R_L_TLS_IE_PC_LO12 B_R_L_TLS_IE_PCALA_0_SK12
> B_R_L_TLS_IE_PC_HI20 B_R_L_TLS_IE_PCALA_12_SJ20
> B_R_L_TLS_IE64_PC_LO20 B_R_L_TLS_IE_PCALA_32_SJ20
> B_R_L_TLS_IE64_PC_HI12 B_R_L_TLS_IE_PCALA_52_SK12
> B_R_L_TLS_IE64_LO12 B_R_L_TLS_IE_ABS_0_SK12
> B_R_L_TLS_IE64_HI20 B_R_L_TLS_IE_ABS_12_SJ20
> B_R_L_TLS_IE64_LO20 B_R_L_TLS_IE_ABS_32_SJ20
> B_R_L_TLS_IE64_HI12 B_R_L_TLS_IE_ABS_52_SK12
> B_R_L_TLS_LD_PC_HI20 B_R_L_TLS_LD_PCALA_12_SJ20 *6
> B_R_L_TLS_LD64_HI20 B_R_L_TLS_LD_ABS_12_SJ20
> B_R_L_TLS_GD_PC_HI20 B_R_L_TLS_GD_PCALA_12_SJ20
> B_R_L_TLS_GD64_HI20 B_R_L_TLS_GD_ABS_12_SJ20
>
> *1 PCREL is explicitly called out. As you can see, every reloc type
> looks like "<purpose>_<starting bit position>_<destination slot>".
> *2 I've reordered the types so that in each group of 4 reloc types
> it's always from LSB to MSB. And while I don't know what "PCALA"
> means, I've kept them all, and distinct from "PCREL" because the jumps
> and PCADDU12I don't clear the lowest 12 bits of destination, thus
> immediates for use with PCALAU12I needs to be differentiated.
> *3 With the starting bit position explicit called out, no "64"
> distinction needs to be made.
> *4 This (and others) actually uses the PCALAU12I, so should be named
> accordingly.
> *5 This (and others) seems like an absolute reloc (it uses the same
> LU12I.W + xxx + LU32I.D + LU52I.D sequence), so ABS is added to name.
> *6 I can't immediately make sense of the last 4 reloc types, but I've
> renamed these too. I would have to dig deeper for understanding the
> expected use case.
>
> And I hope with this proposal, the (bikeshedding) discussion could be
> well-founded and constructive.
>
>> + BFD_RELOC_LARCH_RELAX,
> I see this is just being reserved but without any actual behavior
> specified. Is it better to just leave it out for now?
>
> <snip>
>
>> /* Processor specific flags for the ELF header e_flags field. */
>> @@ -102,9 +238,9 @@ END_RELOC_NUMBERS (R_LARCH_count)
>> #define EF_LOONGARCH_ABI_ILP32_SINGLE_FLOAT 0x6
>> #define EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT 0x7
>> -#define EF_LOONGARCH_ABI_MASK 0x7
>> -#define EF_LOONGARCH_ABI_ILP32_MASK 0x4
>> -#define EF_LOONGARCH_ABI_FLOAT_MASK 0x3
>> +#define EF_LOONGARCH_ABI_MASK 0x7
>> +#define EF_LOONGARCH_ABI_ILP32_MASK 0x4
>> +#define EF_LOONGARCH_ABI_FLOAT_MASK 0x3
>> #define EF_LOONGARCH_ABI_SOFT_FLOAT_MASK 0x1
>> #define EF_LOONGARCH_ABI_SINGLE_FLOAT_MASK 0x2
>> #define EF_LOONGARCH_ABI_DOUBLE_FLOAT_MASK 0x3
> This hunk looks like pure cosmetic change, could this be split out
> (and get committed very quickly unlike the other major changes)?
This may be caused by hand error, the next commit will revert.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-18 12:11 ` WANG Xuerui
2022-07-18 12:18 ` WANG Xuerui
2022-07-19 3:57 ` Fangrui Song
@ 2022-07-20 2:07 ` liuzhensong
2022-07-20 4:03 ` WANG Xuerui
2 siblings, 1 reply; 24+ messages in thread
From: liuzhensong @ 2022-07-20 2:07 UTC (permalink / raw)
To: WANG Xuerui
Cc: Xi Ruoyao, binutils, xuchenghua, mengqinggang, Fangrui Song, huangpei
> -----原始邮件-----
> 发件人: "WANG Xuerui" <i.swmail@xen0n.name>
> 发送时间: 2022-07-18 20:11:27 (星期一)
> 收件人: "Xi Ruoyao" <xry111@xry111.site>, "WANG Xuerui" <i.swmail@xen0n.name>, liuzhensong <liuzhensong@loongson.cn>, binutils@sourceware.org
> 抄送: xuchenghua@loongson.cn, mengqinggang@loongson.cn, "Fangrui Song" <maskray@google.com>
> 主题: Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
>
> On 2022/7/18 19:33, Xi Ruoyao wrote:
> > On Mon, 2022-07-18 at 18:06 +0800, WANG Xuerui wrote:
> >> (Adding Ruoyao and MaskRay to CC, who might be interested in this
> >> development as well, as it concerns the linker implementation.)
> > I've already subscribed binutils@sourceware.org in order not to be
> > passed by.
> >
> >> I think I've voiced my concerns over the naming of these ops multiple
> >> times already; the primary comment ([1]; in English) was posted back in
> >> May but no one in your team responded.
> >>
> >> Reproducing the content (and adjusting a little) here:
> >>
> >>
> >> Overall in a good direction (and IMHO the direction everyone should have
> >> taken in the first place), thanks!
> >>
> > Yes, we've been paying additional costs using those "stack based
> > relocation". I'd like to know why they were proposed in first place?
> > (Not accusing anyone, just my curiosity: AFAIK no other targets ever
> > used such a stack for relocation.)
> As previously pointed out on this list, rx and rl78 both use stack-based
> relocs. (Both come from Renesas, so I do think it's delibrate design
> decision, but of course the original Renesas justification is most
> probably buried in history.) I explained this in
> https://github.com/loongson/binutils-gdb/issues/134 before.
> >
> > /* snip */
> >
> >
> >> FYI, I did make a list of my suggested names for these reloc types
> >> ("BFD_RELOC_LARCH_" abbreviated to "B_R_L_"):
> >>
> >> Original name Suggested name
> >> ------------- --------------
> >> B_R_L_B16 B_R_L_PCREL_SK16 *1
> >> B_R_L_B21 B_R_L_PCREL_SD5K16
> >> B_R_L_B26 B_R_L_PCREL_SD10K16
> >> B_R_L_ABS_LO12 B_R_L_ABS_0_SK12
> >> B_R_L_ABS_HI20 B_R_L_ABS_12_SJ20
> >> B_R_L_ABS64_LO20 B_R_L_ABS_32_SJ20
> >> B_R_L_ABS64_HI12 B_R_L_ABS_52_SK12
> >> B_R_L_PCALA_LO12 B_R_L_PCALA_0_SK12 *2
> >> B_R_L_PCALA_HI20 B_R_L_PCALA_12_SJ20
> >> B_R_L_PCALA64_LO20 B_R_L_PCALA_32_SJ20 *3
> >> B_R_L_PCALA64_HI12 B_R_L_PCALA_52_SK12
> >> B_R_L_GOT_PC_LO12 B_R_L_GOT_PCALA_0_SK12 *4
> >> B_R_L_GOT_PC_HI20 B_R_L_GOT_PCALA_12_SJ20
> >> B_R_L_GOT64_PC_LO20 B_R_L_GOT_PCALA_32_SJ20
> >> B_R_L_GOT64_PC_HI12 B_R_L_GOT_PCALA_52_SK12
> >> B_R_L_GOT64_LO12 B_R_L_GOT_ABS_0_SK12 *5
> >> B_R_L_GOT64_HI20 B_R_L_GOT_ABS_12_SJ20
> >> B_R_L_GOT64_LO20 B_R_L_GOT_ABS_32_SJ20
> >> B_R_L_GOT64_HI12 B_R_L_GOT_ABS_52_SK12
> >> B_R_L_TLS_LE_LO12 B_R_L_TLS_LE_ABS_0_SK12
> >> B_R_L_TLS_LE_HI20 B_R_L_TLS_LE_ABS_12_SJ20
> >> B_R_L_TLS_LE64_LO20 B_R_L_TLS_LE_ABS_32_SJ20
> >> B_R_L_TLS_LE64_HI12 B_R_L_TLS_LE_ABS_52_SK12
> >> B_R_L_TLS_IE_PC_LO12 B_R_L_TLS_IE_PCALA_0_SK12
> >> B_R_L_TLS_IE_PC_HI20 B_R_L_TLS_IE_PCALA_12_SJ20
> >> B_R_L_TLS_IE64_PC_LO20 B_R_L_TLS_IE_PCALA_32_SJ20
> >> B_R_L_TLS_IE64_PC_HI12 B_R_L_TLS_IE_PCALA_52_SK12
> >> B_R_L_TLS_IE64_LO12 B_R_L_TLS_IE_ABS_0_SK12
> >> B_R_L_TLS_IE64_HI20 B_R_L_TLS_IE_ABS_12_SJ20
> >> B_R_L_TLS_IE64_LO20 B_R_L_TLS_IE_ABS_32_SJ20
> >> B_R_L_TLS_IE64_HI12 B_R_L_TLS_IE_ABS_52_SK12
> >> B_R_L_TLS_LD_PC_HI20 B_R_L_TLS_LD_PCALA_12_SJ20 *6
> >> B_R_L_TLS_LD64_HI20 B_R_L_TLS_LD_ABS_12_SJ20
> >> B_R_L_TLS_GD_PC_HI20 B_R_L_TLS_GD_PCALA_12_SJ20
> >> B_R_L_TLS_GD64_HI20 B_R_L_TLS_GD_ABS_12_SJ20
> > It's overall better, but those "J, K" etc are cryptic IMHO. And for
> > "B_R_L_B16" I think "B_R_L_PCREL_SK16" fails to express that the offset
> > should be shifted right by 2, so I'd keep B_R_L_B16 (and similarly,
> > B_R_L_B21 and B_R_L_B26) like the PCALA case.
> >
> The slot names come from
> https://github.com/loongson/LoongArch-Documentation/pull/56 (to
> non-Chinese speakers: English translation still TODO, but hopefully at
> least the ABNF and the few tables should be intelligible even without
> translation).
>
> As for the PCREL and implicit shifts, maybe a planned extension of the
> slot syntax could help. I plan to submit an Assembly Language Convention
> after the Instruction Format Convention gets reviewed and merged, and
> with this new convention such an extension is necessary anyway for
> accommodating the current assembly syntax as described by the ISA
> manual, able to express the <<2's and +1's for the PC-manipulating and
> ALSL insns.
>
> For example, let's say the extension works like this: ordinary slot
> syntax, plus "p", plus an postprocess operator, with "s\d+" for "imm
> slot = assembly operand >> N", and "p\d+" for "imm slot = assembly
> operand + N". Then we could say "B_R_L_PCREL_SK16PS2" and have all the
> niceties. (In an ideal world, the LoongArch opcodes implementation
> should be modified to use this convention too, so for example it will be
> something like "DJSk16ps2" for JIRL, "JDSk16ps2" for BLT (notice the
> reversed operand order) and "DJKUa2pp1" for ALSL insns.
Some relocation name changes make sense. But, how to name a name is a
matter of personal aesthetics, and it is difficult to satisfy everyone.
Does the name of the relocation matter? should we pay more attention to
the specific implementation? Remove useless and add needed?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-18 10:06 ` [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types WANG Xuerui
2022-07-18 11:33 ` Xi Ruoyao
2022-07-19 7:32 ` liuzhensong
@ 2022-07-20 2:42 ` liuzhensong
2 siblings, 0 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-20 2:42 UTC (permalink / raw)
To: WANG Xuerui, binutils; +Cc: xuchenghua, mengqinggang, Xi Ruoyao, Fangrui Song
在 2022/7/18 下午6:06, WANG Xuerui 写道:
> (Adding Ruoyao and MaskRay to CC, who might be interested in this
> development as well, as it concerns the linker implementation.)
>
>
> On 2022/7/18 16:43, liuzhensong wrote:
>
>> This is the v1 version of patches to support new relocs for LoongArch.
>>
>> The new reloc types docnments are on:
>> https://github.com/loongson/LoongArch-Documentation/pull/57/files
>>
>> The testsuite status:
>>
>> === binutils Summary ===
>> # of expected passes 241
>> # of unsupported tests 6
>>
>> === gas Summary ===
>> # of expected passes 270
>> # of unsupported tests 7
>>
>> === ld Summary ===
>> # of expected passes 1457
>> # of expected failures 11
>> # of untested testcases 1
>> # of unsupported tests 154
>>
> I assume the content above are the "cover letter".
>
> BTW: you can generate a proper patch series with `git format-patch -vN
> --cover-letter <base>`; I think the mails in this series were manually
> edited by you since the "v1" is wrongly placed (it's usually "[PATCH
> vN NN/NN]").
>
>> Add new reloc types support, the new relocate type
>> definition depends which operation needs of linker.
> "Define new reloc types according to linker needs" could be enough.
>>
>>
>> ---
>> bfd/bfd-in2.h | 36 ++
>> bfd/elfnn-loongarch.c | 1194 ++++++++++++++++++++++------------
>> bfd/elfxx-loongarch.c | 1354 +++++++++++++++++++++++++++++----------
>> bfd/elfxx-loongarch.h | 4 +
>> bfd/libbfd.h | 36 ++
>> bfd/reloc.c | 79 +++
>> include/elf/loongarch.h | 142 +++-
>> 7 files changed, 2095 insertions(+), 750 deletions(-)
>>
>> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
>> index 4e1182e93d4..a71b3e82057 100644
>> --- a/bfd/bfd-in2.h
>> +++ b/bfd/bfd-in2.h
>> @@ -6274,6 +6274,42 @@ assembler and not (currently) written to any
>> object files. */
>> BFD_RELOC_LARCH_SUB24,
>> BFD_RELOC_LARCH_SUB32,
>> BFD_RELOC_LARCH_SUB64,
>> + BFD_RELOC_LARCH_B16,
>> + BFD_RELOC_LARCH_B21,
>> + BFD_RELOC_LARCH_B26,
>> + BFD_RELOC_LARCH_ABS_HI20,
>> + BFD_RELOC_LARCH_ABS_LO12,
>> + BFD_RELOC_LARCH_ABS64_LO20,
>> + BFD_RELOC_LARCH_ABS64_HI12,
>> + BFD_RELOC_LARCH_PCALA_HI20,
>> + BFD_RELOC_LARCH_PCALA_LO12,
>> + BFD_RELOC_LARCH_PCALA64_LO20,
>> + BFD_RELOC_LARCH_PCALA64_HI12,
>> + BFD_RELOC_LARCH_GOT_PC_HI20,
>> + BFD_RELOC_LARCH_GOT_PC_LO12,
>> + BFD_RELOC_LARCH_GOT64_PC_LO20,
>> + BFD_RELOC_LARCH_GOT64_PC_HI12,
>> + BFD_RELOC_LARCH_GOT64_HI20,
>> + BFD_RELOC_LARCH_GOT64_LO12,
>> + BFD_RELOC_LARCH_GOT64_LO20,
>> + BFD_RELOC_LARCH_GOT64_HI12,
>> + BFD_RELOC_LARCH_TLS_LE_HI20,
>> + BFD_RELOC_LARCH_TLS_LE_LO12,
>> + BFD_RELOC_LARCH_TLS_LE64_LO20,
>> + BFD_RELOC_LARCH_TLS_LE64_HI12,
>> + BFD_RELOC_LARCH_TLS_IE_PC_HI20,
>> + BFD_RELOC_LARCH_TLS_IE_PC_LO12,
>> + BFD_RELOC_LARCH_TLS_IE64_PC_LO20,
>> + BFD_RELOC_LARCH_TLS_IE64_PC_HI12,
>> + BFD_RELOC_LARCH_TLS_IE64_HI20,
>> + BFD_RELOC_LARCH_TLS_IE64_LO12,
>> + BFD_RELOC_LARCH_TLS_IE64_LO20,
>> + BFD_RELOC_LARCH_TLS_IE64_HI12,
>> + BFD_RELOC_LARCH_TLS_LD_PC_HI20,
>> + BFD_RELOC_LARCH_TLS_LD64_HI20,
>> + BFD_RELOC_LARCH_TLS_GD_PC_HI20,
>> + BFD_RELOC_LARCH_TLS_GD64_HI20,
>
> I think I've voiced my concerns over the naming of these ops multiple
> times already; the primary comment ([1]; in English) was posted back
> in May but no one in your team responded.
>
> Reproducing the content (and adjusting a little) here:
>
>
> Overall in a good direction (and IMHO the direction everyone should
> have taken in the first place), thanks! A few suggestions though:
>
> Some of the names can be a bit hard to understand, for example
> ABS_LO12, ABS_HI20, ABS64_LO20 and ABS64_HI12; these are ambiguous on
> a first look, do you use the latter two instead of the former for
> 64-bit absolute relocs? (The answer is "no"; you use all 4. The latter
> two actually express the higher 32-bit half.)
>
> After having trained your intuition to work in "the Loongson way",
> you'll then have to mentally add the "lower/higher half" and "width"
> together to get a picture of the bit-field being expressed. It could
> be better to somehow directly show the 0(LO)/12/32/52 inside those names.
>
> Plus, currently it's implied that a particular relocation type is
> somehow bound to a specific instruction, that's being used by the
> reference implementation (binutils) for the type today. This is being
> a bit too specific, and could change, as future instructions emerge
> with similar or identical format. (BTW no one really understand what
> "ALA" means in "PCALA"; the insn is named "PCALAU12I", the "U12I" part
> is similar to "LU12I.W" thus understandable, and PC is obvious, but no
> explanation for "ALA" exists anywhere). It's better to express the
> "destination" not in terms of instruction names or vague
> "LO12/HI20/LO20/HI12" specifiers, but in terms of actual *instruction
> word slots* being filled. This way it's immediately obvious for anyone
> what place in the insn word the reloc is going to write to, without
> having to dig into actual linker code. However, you don't officially
> have a naming scheme for these, so I guess that's why you have to
> invent names (and be different with others & prior work).
>
> I have drafted my scheme back in November 2021, which I posted at [2]
> a while ago; the approach is extremely similar (IMO there's only one
> possible way to implement the more traditional scheme), but my version
> has adopted the operand slot naming scheme of loongarch-opcodes ([3];
> the convention document is edited and posted at [4] for inclusion in
> official LoongArch docs collection) and the more direct LO/12/32/52
> names for bit-field offsets (width is implied by the destination
> slot). Hope this would be useful.
>
>
> Again, I may sound like a bikeshedder, but IMO better names benefit
> everyone in the long term. I for one definitely don't want to see all
> four of "LO12/HI20/LO20/HI12" (they refer to the two 32-bit halves of
> a 64-bit value, not two ways to segment one 32-bit value), nor
> "B16/B21/B26" (which are more different than you might think).
>
> [1]: https://github.com/loongson/LoongArch-Documentation/pull/50
> [2]:
> https://github.com/loongson/binutils-gdb/issues/134#issuecomment-1110510582
> [3]: https://github.com/loongson-community/loongarch-opcodes
> [4]: https://github.com/loongson/LoongArch-Documentation/pull/56
>
>
> FYI, I did make a list of my suggested names for these reloc types
> ("BFD_RELOC_LARCH_" abbreviated to "B_R_L_"):
>
> Original name Suggested name
> ------------- --------------
> B_R_L_B16 B_R_L_PCREL_SK16 *1
> B_R_L_B21 B_R_L_PCREL_SD5K16
> B_R_L_B26 B_R_L_PCREL_SD10K16
> B_R_L_ABS_LO12 B_R_L_ABS_0_SK12
> B_R_L_ABS_HI20 B_R_L_ABS_12_SJ20
> B_R_L_ABS64_LO20 B_R_L_ABS_32_SJ20
> B_R_L_ABS64_HI12 B_R_L_ABS_52_SK12
> B_R_L_PCALA_LO12 B_R_L_PCALA_0_SK12 *2
> B_R_L_PCALA_HI20 B_R_L_PCALA_12_SJ20
> B_R_L_PCALA64_LO20 B_R_L_PCALA_32_SJ20 *3
> B_R_L_PCALA64_HI12 B_R_L_PCALA_52_SK12
> B_R_L_GOT_PC_LO12 B_R_L_GOT_PCALA_0_SK12 *4
> B_R_L_GOT_PC_HI20 B_R_L_GOT_PCALA_12_SJ20
> B_R_L_GOT64_PC_LO20 B_R_L_GOT_PCALA_32_SJ20
> B_R_L_GOT64_PC_HI12 B_R_L_GOT_PCALA_52_SK12
> B_R_L_GOT64_LO12 B_R_L_GOT_ABS_0_SK12 *5
> B_R_L_GOT64_HI20 B_R_L_GOT_ABS_12_SJ20
> B_R_L_GOT64_LO20 B_R_L_GOT_ABS_32_SJ20
> B_R_L_GOT64_HI12 B_R_L_GOT_ABS_52_SK12
> B_R_L_TLS_LE_LO12 B_R_L_TLS_LE_ABS_0_SK12
> B_R_L_TLS_LE_HI20 B_R_L_TLS_LE_ABS_12_SJ20
> B_R_L_TLS_LE64_LO20 B_R_L_TLS_LE_ABS_32_SJ20
> B_R_L_TLS_LE64_HI12 B_R_L_TLS_LE_ABS_52_SK12
> B_R_L_TLS_IE_PC_LO12 B_R_L_TLS_IE_PCALA_0_SK12
> B_R_L_TLS_IE_PC_HI20 B_R_L_TLS_IE_PCALA_12_SJ20
> B_R_L_TLS_IE64_PC_LO20 B_R_L_TLS_IE_PCALA_32_SJ20
> B_R_L_TLS_IE64_PC_HI12 B_R_L_TLS_IE_PCALA_52_SK12
> B_R_L_TLS_IE64_LO12 B_R_L_TLS_IE_ABS_0_SK12
> B_R_L_TLS_IE64_HI20 B_R_L_TLS_IE_ABS_12_SJ20
> B_R_L_TLS_IE64_LO20 B_R_L_TLS_IE_ABS_32_SJ20
> B_R_L_TLS_IE64_HI12 B_R_L_TLS_IE_ABS_52_SK12
> B_R_L_TLS_LD_PC_HI20 B_R_L_TLS_LD_PCALA_12_SJ20 *6
> B_R_L_TLS_LD64_HI20 B_R_L_TLS_LD_ABS_12_SJ20
> B_R_L_TLS_GD_PC_HI20 B_R_L_TLS_GD_PCALA_12_SJ20
> B_R_L_TLS_GD64_HI20 B_R_L_TLS_GD_ABS_12_SJ20
>
> *1 PCREL is explicitly called out. As you can see, every reloc type
> looks like "<purpose>_<starting bit position>_<destination slot>".
> *2 I've reordered the types so that in each group of 4 reloc types
> it's always from LSB to MSB. And while I don't know what "PCALA"
> means, I've kept them all, and distinct from "PCREL" because the jumps
> and PCADDU12I don't clear the lowest 12 bits of destination, thus
> immediates for use with PCALAU12I needs to be differentiated.
> *3 With the starting bit position explicit called out, no "64"
> distinction needs to be made.
> *4 This (and others) actually uses the PCALAU12I, so should be named
> accordingly.
> *5 This (and others) seems like an absolute reloc (it uses the same
> LU12I.W + xxx + LU32I.D + LU52I.D sequence), so ABS is added to name.
> *6 I can't immediately make sense of the last 4 reloc types, but I've
> renamed these too. I would have to dig deeper for understanding the
> expected use case.
>
> And I hope with this proposal, the (bikeshedding) discussion could be
> well-founded and constructive.
>
>> + BFD_RELOC_LARCH_RELAX,
> I see this is just being reserved but without any actual behavior
> specified. Is it better to just leave it out for now?
This relocation is expected to do some optimizations, do or not won't
affect correctness. The linker has implemented some specific
instructions, but the assembler still has some support that has not been
completed. If it is deleted, the current version linker can not to link
next version object (maybe soon to be patched).
>
> <snip>
>
>> /* Processor specific flags for the ELF header e_flags field. */
>> @@ -102,9 +238,9 @@ END_RELOC_NUMBERS (R_LARCH_count)
>> #define EF_LOONGARCH_ABI_ILP32_SINGLE_FLOAT 0x6
>> #define EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT 0x7
>> -#define EF_LOONGARCH_ABI_MASK 0x7
>> -#define EF_LOONGARCH_ABI_ILP32_MASK 0x4
>> -#define EF_LOONGARCH_ABI_FLOAT_MASK 0x3
>> +#define EF_LOONGARCH_ABI_MASK 0x7
>> +#define EF_LOONGARCH_ABI_ILP32_MASK 0x4
>> +#define EF_LOONGARCH_ABI_FLOAT_MASK 0x3
>> #define EF_LOONGARCH_ABI_SOFT_FLOAT_MASK 0x1
>> #define EF_LOONGARCH_ABI_SINGLE_FLOAT_MASK 0x2
>> #define EF_LOONGARCH_ABI_DOUBLE_FLOAT_MASK 0x3
> This hunk looks like pure cosmetic change, could this be split out
> (and get committed very quickly unlike the other major changes)?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-20 2:07 ` liuzhensong
@ 2022-07-20 4:03 ` WANG Xuerui
2022-07-20 5:19 ` Xi Ruoyao
2022-07-20 12:54 ` liuzhensong
0 siblings, 2 replies; 24+ messages in thread
From: WANG Xuerui @ 2022-07-20 4:03 UTC (permalink / raw)
To: liuzhensong, WANG Xuerui
Cc: Xi Ruoyao, binutils, xuchenghua, mengqinggang, Fangrui Song, huangpei
On 2022/7/20 10:07, liuzhensong wrote:
>
> Some relocation name changes make sense. But, how to name a name is a
> matter of personal aesthetics, and it is difficult to satisfy
> everyone. Does the name of the relocation matter? should we pay more
> attention to the specific implementation? Remove useless and add needed?
>
Names do matter. You can't expect to lower maintenance costs and barrier
to entry for newcomers with "bad" names. I showed the original names in
the patch to some of my colleagues (with no low-level programming
experience; they are all application developers), and they invariably
can't get the distinction of "LO12/HI20/LO20/HI12". I then showed them
my proposal, granted they needed a little explanation as to what things
like "SK12" mean, but after that they can immediately get the feel of
the relocs ("ah, it's like for this purpose, put this part of imm into
this slot").
LoongArch is expected to remain niche, at least for the coming 3~5
years, so you can't expect to have many people working on low-level
nitty-gritty details like this. I personally don't think your team's
composition is going to remain stable over the years, either; in either
case, people come and go, so IMO there is indeed value in this
bikeshedding. The community as a whole can work over concrete proposals
of better naming, and I think my proposal serves as such a constructive
starting point.
Also, if you think the current names are more appropriate, with
objective reasons, then *please communicate* your justification and
thought behind them. We "outsiders" actually intend to cooperate, and
have voiced our thoughts, but we don't know what you and your team
think. For now all we have is this "LO12/HI20/LO20/HI12" and outsiders
can draw no conclusion other than "hmm this is going to cause
confusion". We really need to communicate more in the open for pushing
things forward, constructively.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-20 4:03 ` WANG Xuerui
@ 2022-07-20 5:19 ` Xi Ruoyao
2022-07-20 12:54 ` liuzhensong
1 sibling, 0 replies; 24+ messages in thread
From: Xi Ruoyao @ 2022-07-20 5:19 UTC (permalink / raw)
To: WANG Xuerui, liuzhensong
Cc: binutils, xuchenghua, mengqinggang, Fangrui Song, huangpei
On Wed, 2022-07-20 at 12:03 +0800, WANG Xuerui wrote:
> On 2022/7/20 10:07, liuzhensong wrote:
> >
> > Some relocation name changes make sense. But, how to name a name is a
> > matter of personal aesthetics, and it is difficult to satisfy
> > everyone. Does the name of the relocation matter? should we pay more
> > attention to the specific implementation? Remove useless and add needed?
A bug fix needs immediately attention, but a new feature may need more
discussion to make it easier to be used correctly. I'm still reluctant
about "adding a whole bunch of new relocation just 3 weeks before
Binutils-2.39 release date".
>
> Also, if you think the current names are more appropriate, with
> objective reasons, then *please communicate* your justification and
> thought behind them. We "outsiders" actually intend to cooperate, and
> have voiced our thoughts, but we don't know what you and your team
> think. For now all we have is this "LO12/HI20/LO20/HI12" and outsiders
> can draw no conclusion other than "hmm this is going to cause
> confusion". We really need to communicate more in the open for pushing
> things forward, constructively.
About "LO12/HI20/LO20/HI12" vs "0/12/32/52", please consider: if someone
has not read LoongArch manual, he'll have no idea about what is "HI20"
and likely [mis]interpret it as "x[63:44]" instead of "x[51:32]". But
if he has read LoongArch manual, the manual already uses
"LU12I.W/LU32I.D/LU52I.D". So a different notion for the parts of
immediate seems a completely unnecessary deviation.
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-19 3:57 ` Fangrui Song
@ 2022-07-20 7:47 ` liuzhensong
0 siblings, 0 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-20 7:47 UTC (permalink / raw)
To: Fangrui Song, WANG Xuerui; +Cc: Xi Ruoyao, binutils, xuchenghua, mengqinggang
在 2022/7/19 上午11:57, Fangrui Song 写道:
> On 2022-07-18, WANG Xuerui wrote:
>> On 2022/7/18 19:33, Xi Ruoyao wrote:
>>> On Mon, 2022-07-18 at 18:06 +0800, WANG Xuerui wrote:
>>>> (Adding Ruoyao and MaskRay to CC, who might be interested in this
>>>> development as well, as it concerns the linker implementation.)
>>> I've already subscribed binutils@sourceware.org in order not to be
>>> passed by.
>
> I am subscribed, too. Direct CC helps me find the discussions:)
>
>>>> I think I've voiced my concerns over the naming of these ops multiple
>>>> times already; the primary comment ([1]; in English) was posted
>>>> back in
>>>> May but no one in your team responded.
>>>>
>>>> Reproducing the content (and adjusting a little) here:
>>>>
>>>>
>>>> Overall in a good direction (and IMHO the direction everyone should
>>>> have
>>>> taken in the first place), thanks!
>>>>
>>> Yes, we've been paying additional costs using those "stack based
>>> relocation". I'd like to know why they were proposed in first place?
>>> (Not accusing anyone, just my curiosity: AFAIK no other targets ever
>>> used such a stack for relocation.)
>> As previously pointed out on this list, rx and rl78 both use
>> stack-based relocs. (Both come from Renesas, so I do think it's
>> delibrate design decision, but of course the original Renesas
>> justification is most probably buried in history.) I explained this
>> in https://github.com/loongson/binutils-gdb/issues/134 before.
>
> Stack machines aren't really suitable for ELF relocations.
> Each relocation takes sizeof(Elf64_Rela) = 24 byte, higher than older
> object file formats.
>
> ELF32 allows 256 relocation types. There aren't too many to waste.
>
>>>
>>> /* snip */
>>>
>>>
>>>> FYI, I did make a list of my suggested names for these reloc types
>>>> ("BFD_RELOC_LARCH_" abbreviated to "B_R_L_"):
>>>>
>>>> Original name Suggested name
>>>> ------------- --------------
>>>> B_R_L_B16 B_R_L_PCREL_SK16 *1
>>>> B_R_L_B21 B_R_L_PCREL_SD5K16
>>>> B_R_L_B26 B_R_L_PCREL_SD10K16
>>>> B_R_L_ABS_LO12 B_R_L_ABS_0_SK12
>>>> B_R_L_ABS_HI20 B_R_L_ABS_12_SJ20
>>>> B_R_L_ABS64_LO20 B_R_L_ABS_32_SJ20
>>>> B_R_L_ABS64_HI12 B_R_L_ABS_52_SK12
>
> aarch64 calls these G0/G1/G2/G3 while ppc calls these
> LO/HI/HIGHER/HIGHEST.
> A name mentioning the offset and the length looks good to me, too.
> A too-long name may have problems in the default (non-wide) output of
> readelf -r.
>
>>>> B_R_L_PCALA_LO12 B_R_L_PCALA_0_SK12 *2
>>>> B_R_L_PCALA_HI20 B_R_L_PCALA_12_SJ20
>>>> B_R_L_PCALA64_LO20 B_R_L_PCALA_32_SJ20 *3
>>>> B_R_L_PCALA64_HI12 B_R_L_PCALA_52_SK12
>>>> B_R_L_GOT_PC_LO12 B_R_L_GOT_PCALA_0_SK12 *4
>>>> B_R_L_GOT_PC_HI20 B_R_L_GOT_PCALA_12_SJ20
>>>> B_R_L_GOT64_PC_LO20 B_R_L_GOT_PCALA_32_SJ20
>>>> B_R_L_GOT64_PC_HI12 B_R_L_GOT_PCALA_52_SK12
>>>> B_R_L_GOT64_LO12 B_R_L_GOT_ABS_0_SK12 *5
>>>> B_R_L_GOT64_HI20 B_R_L_GOT_ABS_12_SJ20
>>>> B_R_L_GOT64_LO20 B_R_L_GOT_ABS_32_SJ20
>>>> B_R_L_GOT64_HI12 B_R_L_GOT_ABS_52_SK12
>
>
>>>> B_R_L_TLS_LE_LO12 B_R_L_TLS_LE_ABS_0_SK12
>>>> B_R_L_TLS_LE_HI20 B_R_L_TLS_LE_ABS_12_SJ20
>>>> B_R_L_TLS_LE64_LO20 B_R_L_TLS_LE_ABS_32_SJ20
>>>> B_R_L_TLS_LE64_HI12 B_R_L_TLS_LE_ABS_52_SK12
>>>> B_R_L_TLS_IE_PC_LO12 B_R_L_TLS_IE_PCALA_0_SK12
>>>> B_R_L_TLS_IE_PC_HI20 B_R_L_TLS_IE_PCALA_12_SJ20
>>>> B_R_L_TLS_IE64_PC_LO20 B_R_L_TLS_IE_PCALA_32_SJ20
>>>> B_R_L_TLS_IE64_PC_HI12 B_R_L_TLS_IE_PCALA_52_SK12
>>>> B_R_L_TLS_IE64_LO12 B_R_L_TLS_IE_ABS_0_SK12
>>>> B_R_L_TLS_IE64_HI20 B_R_L_TLS_IE_ABS_12_SJ20
>>>> B_R_L_TLS_IE64_LO20 B_R_L_TLS_IE_ABS_32_SJ20
>>>> B_R_L_TLS_IE64_HI12 B_R_L_TLS_IE_ABS_52_SK12
>>>> B_R_L_TLS_LD_PC_HI20 B_R_L_TLS_LD_PCALA_12_SJ20 *6
>>>> B_R_L_TLS_LD64_HI20 B_R_L_TLS_LD_ABS_12_SJ20
>>>> B_R_L_TLS_GD_PC_HI20 B_R_L_TLS_GD_PCALA_12_SJ20
>>>> B_R_L_TLS_GD64_HI20 B_R_L_TLS_GD_ABS_12_SJ20
>
> aarch64 relocation types are well named. It's obvious what suppress
> overflow checking.
>
> For LO12, I expect that there are two variants: one with overflow check,
> the other without.
>
In what scenarios will no check overflow be used? Any documentation or
examples?
>>> It's overall better, but those "J, K" etc are cryptic IMHO. And for
>>> "B_R_L_B16" I think "B_R_L_PCREL_SK16" fails to express that the offset
>>> should be shifted right by 2, so I'd keep B_R_L_B16 (and similarly,
>>> B_R_L_B21 and B_R_L_B26) like the PCALA case.
>>>
>> The slot names come from
>> https://github.com/loongson/LoongArch-Documentation/pull/56 (to
>> non-Chinese speakers: English translation still TODO, but hopefully
>> at least the ABNF and the few tables should be intelligible even
>> without translation).
>>
>> As for the PCREL and implicit shifts, maybe a planned extension of
>> the slot syntax could help. I plan to submit an Assembly Language
>> Convention after the Instruction Format Convention gets reviewed and
>> merged, and with this new convention such an extension is necessary
>> anyway for accommodating the current assembly syntax as described by
>> the ISA manual, able to express the <<2's and +1's for the
>> PC-manipulating and ALSL insns.
>>
>> For example, let's say the extension works like this: ordinary slot
>> syntax, plus "p", plus an postprocess operator, with "s\d+" for "imm
>> slot = assembly operand >> N", and "p\d+" for "imm slot = assembly
>> operand + N". Then we could say "B_R_L_PCREL_SK16PS2" and have all
>> the niceties. (In an ideal world, the LoongArch opcodes
>> implementation should be modified to use this convention too, so for
>> example it will be something like "DJSk16ps2" for JIRL, "JDSk16ps2"
>> for BLT (notice the reversed operand order) and "DJKUa2pp1" for ALSL
>> insns.
>>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types.
2022-07-20 4:03 ` WANG Xuerui
2022-07-20 5:19 ` Xi Ruoyao
@ 2022-07-20 12:54 ` liuzhensong
1 sibling, 0 replies; 24+ messages in thread
From: liuzhensong @ 2022-07-20 12:54 UTC (permalink / raw)
To: WANG Xuerui
Cc: Xi Ruoyao, binutils, xuchenghua, mengqinggang, Fangrui Song, huangpei
在 2022/7/20 下午12:03, WANG Xuerui 写道:
> On 2022/7/20 10:07, liuzhensong wrote:
>>
>> Some relocation name changes make sense. But, how to name a name is a
>> matter of personal aesthetics, and it is difficult to satisfy
>> everyone. Does the name of the relocation matter? should we pay more
>> attention to the specific implementation? Remove useless and add
>> needed?
>>
> Names do matter. You can't expect to lower maintenance costs and
> barrier to entry for newcomers with "bad" names. I showed the original
> names in the patch to some of my colleagues (with no low-level
> programming experience; they are all application developers), and they
> invariably can't get the distinction of "LO12/HI20/LO20/HI12". I then
> showed them my proposal, granted they needed a little explanation as
> to what things like "SK12" mean, but after that they can immediately
> get the feel of the relocs ("ah, it's like for this purpose, put this
> part of imm into this slot").
>
> LoongArch is expected to remain niche, at least for the coming 3~5
> years, so you can't expect to have many people working on low-level
> nitty-gritty details like this. I personally don't think your team's
> composition is going to remain stable over the years, either; in
> either case, people come and go, so IMO there is indeed value in this
> bikeshedding. The community as a whole can work over concrete
> proposals of better naming, and I think my proposal serves as such a
> constructive starting point.
>
> Also, if you think the current names are more appropriate, with
> objective reasons, then *please communicate* your justification and
> thought behind them. We "outsiders" actually intend to cooperate, and
> have voiced our thoughts, but we don't know what you and your team
> think. For now all we have is this "LO12/HI20/LO20/HI12" and outsiders
> can draw no conclusion other than "hmm this is going to cause
> confusion". We really need to communicate more in the open for pushing
> things forward, constructively.
Your relocation is fine, but it's a bit long and complicated and
informative(personaly opinion). It seems unlikely to modify code just by
relocation name, there is necessary to understand the instructions
represented by relocation.
I made some adjustments to some relocations, then, LO12 and HI20
implement 32-bit relocation, xxx64_LO20 and xxx64_HI12 implement high
32bits of 64-bit relocation while low 32bits use LO12 and HI20. In my
opinion, it is enough to know what to do by name.
LO12 [11:0] HI20 [31:12] 64_LO20 [51:32] 64_HI12 [63:52] Changes,
1. B_R_L_GOT64_LO12 B_R_L_GOT_LO12
2. B_R_L_GOT64_HI20 B_R_L_GOT_HI20
3. B_R_L_TLS64_IE_LO12 B_R_L_TLS_IE_LO12
4. B_R_L_TLS64_IE_HI20 B_R_L_TLS_IE_HI20
5. B_R_L_TLS64_LD_HI20 B_R_L_TLS_LD_HI20
6. B_R_L_TLS64_GD_HI20 B_R_L_TLS_GD_HI20
Original name Suggested name
------------- --------------
B_R_L_B16 B_R_L_PCREL_SK16
B_R_L_B21 B_R_L_PCREL_SD5K16
B_R_L_B26 B_R_L_PCREL_SD10K16
B_R_L_ABS_LO12 B_R_L_ABS_0_SK12
B_R_L_ABS_HI20 B_R_L_ABS_12_SJ20
B_R_L_ABS64_LO20 B_R_L_ABS_32_SJ20
B_R_L_ABS64_HI12 B_R_L_ABS_52_SK12
B_R_L_PCALA_LO12 B_R_L_PCALA_0_SK12
B_R_L_PCALA_HI20 B_R_L_PCALA_12_SJ20
B_R_L_PCALA64_LO20 B_R_L_PCALA_32_SJ20
B_R_L_PCALA64_HI12 B_R_L_PCALA_52_SK12
B_R_L_GOT_PC_LO12 B_R_L_GOT_PCALA_0_SK12
B_R_L_GOT_PC_HI20 B_R_L_GOT_PCALA_12_SJ20
B_R_L_GOT64_PC_LO20 B_R_L_GOT_PCALA_32_SJ20
B_R_L_GOT64_PC_HI12 B_R_L_GOT_PCALA_52_SK12
1. B_R_L_GOT_LO12 B_R_L_GOT_ABS_0_SK12
2. B_R_L_GOT_HI20 B_R_L_GOT_ABS_12_SJ20
B_R_L_GOT64_LO20 B_R_L_GOT_ABS_32_SJ20
B_R_L_GOT64_HI12 B_R_L_GOT_ABS_52_SK12
B_R_L_TLS_LE_LO12 B_R_L_TLS_LE_ABS_0_SK12
B_R_L_TLS_LE_HI20 B_R_L_TLS_LE_ABS_12_SJ20
B_R_L_TLS_LE64_LO20 B_R_L_TLS_LE_ABS_32_SJ20
B_R_L_TLS_LE64_HI12 B_R_L_TLS_LE_ABS_52_SK12
B_R_L_TLS_IE_PC_LO12 B_R_L_TLS_IE_PCALA_0_SK12
B_R_L_TLS_IE_PC_HI20 B_R_L_TLS_IE_PCALA_12_SJ20
B_R_L_TLS_IE64_PC_LO20 B_R_L_TLS_IE_PCALA_32_SJ20
B_R_L_TLS_IE64_PC_HI12 B_R_L_TLS_IE_PCALA_52_SK12
3. B_R_L_TLS_IE_LO12 B_R_L_TLS_IE_ABS_0_SK12
4. B_R_L_TLS_IE_HI20 B_R_L_TLS_IE_ABS_12_SJ20
B_R_L_TLS_IE64_LO20 B_R_L_TLS_IE_ABS_32_SJ20
B_R_L_TLS_IE64_HI12 B_R_L_TLS_IE_ABS_52_SK12
B_R_L_TLS_LD_PC_HI20 B_R_L_TLS_LD_PCALA_12_SJ20
5. B_R_L_TLS_LD_HI20 B_R_L_TLS_LD_ABS_12_SJ20
B_R_L_TLS_GD_PC_HI20 B_R_L_TLS_GD_PCALA_12_SJ20
6. B_R_L_TLS_GD_HI20 B_R_L_TLS_GD_ABS_12_SJ20
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2022-07-20 12:54 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-18 8:43 [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types liuzhensong
2022-07-18 8:43 ` [PATCH 2/5 v1] LoongArch:opcodes: " liuzhensong
2022-07-18 8:43 ` [PATCH 3/5 v1] LoongArch: gas: " liuzhensong
2022-07-18 8:43 ` [PATCH 4/5 v1] LoongArch: Move ifunc info to rela.dyn from rela.plt liuzhensong
2022-07-18 11:45 ` Xi Ruoyao
2022-07-18 16:27 ` Xi Ruoyao
2022-07-19 7:26 ` liuzhensong
2022-07-18 8:43 ` [PATCH 5/5 v1] LoongArch: Delete R_LARCH_NONE from dynamic info liuzhensong
2022-07-18 10:06 ` [PATCH 1/5 v1] LoongArch: bfd: Add new reloc types WANG Xuerui
2022-07-18 11:33 ` Xi Ruoyao
2022-07-18 12:11 ` WANG Xuerui
2022-07-18 12:18 ` WANG Xuerui
2022-07-19 3:57 ` Fangrui Song
2022-07-20 7:47 ` liuzhensong
2022-07-20 2:07 ` liuzhensong
2022-07-20 4:03 ` WANG Xuerui
2022-07-20 5:19 ` Xi Ruoyao
2022-07-20 12:54 ` liuzhensong
2022-07-19 7:32 ` liuzhensong
2022-07-20 2:42 ` liuzhensong
2022-07-19 4:29 ` Xi Ruoyao
2022-07-19 5:40 ` Xi Ruoyao
2022-07-19 6:31 ` 刘振松
2022-07-19 6:34 ` Xi Ruoyao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).