RISC-V: Clarify the addends of pc-relative access.
The original discussion was here, https://github.com/riscv/riscv-elf-psabi-doc/issues/184 After discussing with Kito Cheng, I think the addends of %pcrel_hi and %pcrel_lo are both allowed in GNU toolchain. However, both of the them mean the offset of symbols, rather than the pc address. But the addends of %got_pcrel_hi and it's %pcrel_lo do not look reasonable. I believe gcc won't generate the got patterns with addends, so linker should report dangerous relocation errors, in case the assembly code use them. Another issue was here, https://sourceware.org/pipermail/binutils/2021-June/116983.html At the beginnig, I suppose %pcrel_hi and %pcrel_lo are valid only when they are in the same input section. But Jim Wilson points out that gcc may generate %hi and %lo in the different input sections, when -freorder-blocks-and-partition option is used. So that a memory references for a loop may have the %hi outside the loop, but the %lo remain in the loop. However, it is hard to create the testcases, to see if %pcrel_hi and %pcrel_lo have the same behavior. Unfortunately, I notice that the current pcrel resolver cannot work for the above case. For now we build a hash table for pcrel at the start of riscv_elf_relocate_section, and then free the hash at the end. But riscv_elf_relocate_section only handles an input section at a time, so that means we can only resolve the %pcrel_hi and %pcrel_lo which are in the same input section. Otherwise, like the above case, we will report "%pcrel_lo missing matching %pcrel_hi" for them. I have no plan to improve this in the short-term, so maybe we can wait until someone meets the problem before we deal with it. bfd/ * elfnn-riscv.c (riscv_pcrel_hi_reloc): Added field to store the original relocation type, in case the type is converted to R_RISCV_HI20. (riscv_pcrel_lo_reloc): Removed unused name field. (riscv_pcrel_relocs): Added comments. (riscv_zero_pcrel_hi_reloc): Removed unused input_bfd. (riscv_record_pcrel_hi_reloc): Updated. (riscv_record_pcrel_lo_reloc): Likewise. (riscv_resolve_pcrel_lo_relocs): Likewise. Check the original type of auipc, to make sure the %pcrel_lo without any addends. Otherwise, report dangerous relocation error. (riscv_elf_relocate_section): Updated above functions are changed. For R_RISCV_GOT_HI20, report dangerous relocation error when addend isn't zero. ld/ * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated. * testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d: New testcase. * testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s: Likewise. * testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d: New testcase. Should report error since the %pcrel_lo with addend refers to %got_pcrel_hi. * testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s: Likewise. * testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d: New testcase. Should report error since the %got_pcrel_hi with addend. * testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s: Likewise. * testsuite/ld-riscv-elf/pcrel-lo-addend-3.ld: Likewise.
This commit is contained in:
parent
80dc83fd0e
commit
50331d64f1
@ -1,3 +1,20 @@
|
||||
2021-06-22 Nelson Chu <nelson.chu@sifive.com>
|
||||
|
||||
* elfnn-riscv.c (riscv_pcrel_hi_reloc): Added field to store
|
||||
the original relocation type, in case the type is converted to
|
||||
R_RISCV_HI20.
|
||||
(riscv_pcrel_lo_reloc): Removed unused name field.
|
||||
(riscv_pcrel_relocs): Added comments.
|
||||
(riscv_zero_pcrel_hi_reloc): Removed unused input_bfd.
|
||||
(riscv_record_pcrel_hi_reloc): Updated.
|
||||
(riscv_record_pcrel_lo_reloc): Likewise.
|
||||
(riscv_resolve_pcrel_lo_relocs): Likewise. Check the original
|
||||
type of auipc, to make sure the %pcrel_lo without any addends.
|
||||
Otherwise, report dangerous relocation error.
|
||||
(riscv_elf_relocate_section): Updated above functions are changed.
|
||||
For R_RISCV_GOT_HI20, report dangerous relocation error when addend
|
||||
isn't zero.
|
||||
|
||||
2021-06-19 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/27998
|
||||
|
@ -1739,25 +1739,41 @@ perform_relocation (const reloc_howto_type *howto,
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* PC value. */
|
||||
bfd_vma address;
|
||||
/* Relocation value with addend. */
|
||||
bfd_vma value;
|
||||
/* Original reloc type. */
|
||||
int type;
|
||||
} riscv_pcrel_hi_reloc;
|
||||
|
||||
typedef struct riscv_pcrel_lo_reloc
|
||||
{
|
||||
/* PC value of auipc. */
|
||||
bfd_vma address;
|
||||
/* Internal relocation. */
|
||||
const Elf_Internal_Rela *reloc;
|
||||
/* Record the following information helps to resolve the %pcrel
|
||||
which cross different input section. For now we build a hash
|
||||
for pcrel at the start of riscv_elf_relocate_section, and then
|
||||
free the hash at the end. But riscv_elf_relocate_section only
|
||||
handles an input section at a time, so that means we can only
|
||||
resolve the %pcrel_hi and %pcrel_lo which are in the same input
|
||||
section. Otherwise, we will report dangerous relocation errors
|
||||
for those %pcrel which are not in the same input section. */
|
||||
asection *input_section;
|
||||
struct bfd_link_info *info;
|
||||
reloc_howto_type *howto;
|
||||
const Elf_Internal_Rela *reloc;
|
||||
bfd_vma addr;
|
||||
const char *name;
|
||||
bfd_byte *contents;
|
||||
/* The next riscv_pcrel_lo_reloc. */
|
||||
struct riscv_pcrel_lo_reloc *next;
|
||||
} riscv_pcrel_lo_reloc;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Hash table for riscv_pcrel_hi_reloc. */
|
||||
htab_t hi_relocs;
|
||||
/* Linked list for riscv_pcrel_lo_reloc. */
|
||||
riscv_pcrel_lo_reloc *lo_relocs;
|
||||
} riscv_pcrel_relocs;
|
||||
|
||||
@ -1805,8 +1821,7 @@ riscv_zero_pcrel_hi_reloc (Elf_Internal_Rela *rel,
|
||||
bfd_vma pc,
|
||||
bfd_vma addr,
|
||||
bfd_byte *contents,
|
||||
const reloc_howto_type *howto,
|
||||
bfd *input_bfd ATTRIBUTE_UNUSED)
|
||||
const reloc_howto_type *howto)
|
||||
{
|
||||
/* We may need to reference low addreses in PC-relative modes even when the
|
||||
PC is far away from these addresses. For example, undefweak references
|
||||
@ -1839,11 +1854,14 @@ riscv_zero_pcrel_hi_reloc (Elf_Internal_Rela *rel,
|
||||
}
|
||||
|
||||
static bool
|
||||
riscv_record_pcrel_hi_reloc (riscv_pcrel_relocs *p, bfd_vma addr,
|
||||
bfd_vma value, bool absolute)
|
||||
riscv_record_pcrel_hi_reloc (riscv_pcrel_relocs *p,
|
||||
bfd_vma addr,
|
||||
bfd_vma value,
|
||||
int type,
|
||||
bool absolute)
|
||||
{
|
||||
bfd_vma offset = absolute ? value : value - addr;
|
||||
riscv_pcrel_hi_reloc entry = {addr, offset};
|
||||
riscv_pcrel_hi_reloc entry = {addr, offset, type};
|
||||
riscv_pcrel_hi_reloc **slot =
|
||||
(riscv_pcrel_hi_reloc **) htab_find_slot (p->hi_relocs, &entry, INSERT);
|
||||
|
||||
@ -1857,20 +1875,19 @@ riscv_record_pcrel_hi_reloc (riscv_pcrel_relocs *p, bfd_vma addr,
|
||||
|
||||
static bool
|
||||
riscv_record_pcrel_lo_reloc (riscv_pcrel_relocs *p,
|
||||
bfd_vma addr,
|
||||
const Elf_Internal_Rela *reloc,
|
||||
asection *input_section,
|
||||
struct bfd_link_info *info,
|
||||
reloc_howto_type *howto,
|
||||
const Elf_Internal_Rela *reloc,
|
||||
bfd_vma addr,
|
||||
const char *name,
|
||||
bfd_byte *contents)
|
||||
{
|
||||
riscv_pcrel_lo_reloc *entry;
|
||||
entry = (riscv_pcrel_lo_reloc *) bfd_malloc (sizeof (riscv_pcrel_lo_reloc));
|
||||
if (entry == NULL)
|
||||
return false;
|
||||
*entry = (riscv_pcrel_lo_reloc) {input_section, info, howto, reloc, addr,
|
||||
name, contents, p->lo_relocs};
|
||||
*entry = (riscv_pcrel_lo_reloc) {addr, reloc, input_section, info,
|
||||
howto, contents, p->lo_relocs};
|
||||
p->lo_relocs = entry;
|
||||
return true;
|
||||
}
|
||||
@ -1884,17 +1901,22 @@ riscv_resolve_pcrel_lo_relocs (riscv_pcrel_relocs *p)
|
||||
{
|
||||
bfd *input_bfd = r->input_section->owner;
|
||||
|
||||
riscv_pcrel_hi_reloc search = {r->addr, 0};
|
||||
riscv_pcrel_hi_reloc search = {r->address, 0, 0};
|
||||
riscv_pcrel_hi_reloc *entry = htab_find (p->hi_relocs, &search);
|
||||
if (entry == NULL
|
||||
/* Check the overflow when adding reloc addend. */
|
||||
|| (RISCV_CONST_HIGH_PART (entry->value)
|
||||
!= RISCV_CONST_HIGH_PART (entry->value + r->reloc->r_addend)))
|
||||
{
|
||||
char *string;
|
||||
/* There may be a risk if the %pcrel_lo with addend refers to
|
||||
an IFUNC symbol. The %pcrel_hi has been relocated to plt,
|
||||
so the corresponding %pcrel_lo with addend looks wrong. */
|
||||
char *string = NULL;
|
||||
if (entry == NULL)
|
||||
string = _("%pcrel_lo missing matching %pcrel_hi");
|
||||
else if (asprintf (&string,
|
||||
else if (entry->type == R_RISCV_GOT_HI20
|
||||
&& r->reloc->r_addend != 0)
|
||||
string = _("%pcrel_lo with addend isn't allowed for R_RISCV_GOT_HI20");
|
||||
else if (RISCV_CONST_HIGH_PART (entry->value)
|
||||
!= RISCV_CONST_HIGH_PART (entry->value + r->reloc->r_addend))
|
||||
{
|
||||
/* Check the overflow when adding reloc addend. */
|
||||
if (asprintf (&string,
|
||||
_("%%pcrel_lo overflow with an addend, the "
|
||||
"value of %%pcrel_hi is 0x%" PRIx64 " without "
|
||||
"any addend, but may be 0x%" PRIx64 " after "
|
||||
@ -1903,7 +1925,10 @@ riscv_resolve_pcrel_lo_relocs (riscv_pcrel_relocs *p)
|
||||
(int64_t) RISCV_CONST_HIGH_PART
|
||||
(entry->value + r->reloc->r_addend)) == -1)
|
||||
string = _("%pcrel_lo overflow with an addend");
|
||||
}
|
||||
|
||||
if (string != NULL)
|
||||
{
|
||||
(*r->info->callbacks->reloc_dangerous)
|
||||
(r->info, string, input_bfd, r->input_section, r->reloc->r_offset);
|
||||
return true;
|
||||
@ -2225,12 +2250,9 @@ riscv_elf_relocate_section (bfd *output_bfd,
|
||||
relocation = base_got->output_section->vma
|
||||
+ base_got->output_offset + off;
|
||||
|
||||
r_type = ELFNN_R_TYPE (rel->r_info);
|
||||
howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
|
||||
if (howto == NULL)
|
||||
r = bfd_reloc_notsupported;
|
||||
else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
|
||||
relocation, false))
|
||||
if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
|
||||
relocation, r_type,
|
||||
false))
|
||||
r = bfd_reloc_overflow;
|
||||
goto do_relocation;
|
||||
|
||||
@ -2242,12 +2264,9 @@ riscv_elf_relocate_section (bfd *output_bfd,
|
||||
goto do_relocation;
|
||||
|
||||
case R_RISCV_PCREL_HI20:
|
||||
r_type = ELFNN_R_TYPE (rel->r_info);
|
||||
howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
|
||||
if (howto == NULL)
|
||||
r = bfd_reloc_notsupported;
|
||||
else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
|
||||
relocation, false))
|
||||
if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
|
||||
relocation, r_type,
|
||||
false))
|
||||
r = bfd_reloc_overflow;
|
||||
goto do_relocation;
|
||||
|
||||
@ -2384,21 +2403,29 @@ riscv_elf_relocate_section (bfd *output_bfd,
|
||||
local_got_offsets[r_symndx] |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (rel->r_addend != 0)
|
||||
{
|
||||
msg = _("The addend isn't allowed for R_RISCV_GOT_HI20");
|
||||
r = bfd_reloc_dangerous;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Address of got entry. */
|
||||
relocation = sec_addr (htab->elf.sgot) + off;
|
||||
absolute = riscv_zero_pcrel_hi_reloc (rel,
|
||||
info,
|
||||
pc,
|
||||
relocation,
|
||||
contents,
|
||||
howto,
|
||||
input_bfd);
|
||||
r_type = ELFNN_R_TYPE (rel->r_info);
|
||||
howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
|
||||
absolute = riscv_zero_pcrel_hi_reloc (rel, info, pc,
|
||||
relocation, contents,
|
||||
howto);
|
||||
/* Update howto if relocation is changed. */
|
||||
howto = riscv_elf_rtype_to_howto (input_bfd,
|
||||
ELFNN_R_TYPE (rel->r_info));
|
||||
if (howto == NULL)
|
||||
r = bfd_reloc_notsupported;
|
||||
else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
|
||||
relocation, absolute))
|
||||
relocation, r_type,
|
||||
absolute))
|
||||
r = bfd_reloc_overflow;
|
||||
}
|
||||
break;
|
||||
|
||||
case R_RISCV_ADD8:
|
||||
@ -2499,20 +2526,16 @@ riscv_elf_relocate_section (bfd *output_bfd,
|
||||
}
|
||||
|
||||
case R_RISCV_PCREL_HI20:
|
||||
absolute = riscv_zero_pcrel_hi_reloc (rel,
|
||||
info,
|
||||
pc,
|
||||
relocation,
|
||||
contents,
|
||||
howto,
|
||||
input_bfd);
|
||||
r_type = ELFNN_R_TYPE (rel->r_info);
|
||||
howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
|
||||
absolute = riscv_zero_pcrel_hi_reloc (rel, info, pc, relocation,
|
||||
contents, howto);
|
||||
/* Update howto if relocation is changed. */
|
||||
howto = riscv_elf_rtype_to_howto (input_bfd,
|
||||
ELFNN_R_TYPE (rel->r_info));
|
||||
if (howto == NULL)
|
||||
r = bfd_reloc_notsupported;
|
||||
else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
|
||||
relocation + rel->r_addend,
|
||||
absolute))
|
||||
r_type, absolute))
|
||||
r = bfd_reloc_overflow;
|
||||
break;
|
||||
|
||||
@ -2532,8 +2555,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
}
|
||||
|
||||
if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, input_section, info,
|
||||
howto, rel, relocation, name,
|
||||
if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, relocation, rel,
|
||||
input_section, info, howto,
|
||||
contents))
|
||||
continue;
|
||||
r = bfd_reloc_overflow;
|
||||
@ -2726,7 +2749,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
|
||||
BFD_ASSERT (off < (bfd_vma) -2);
|
||||
relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off : 0);
|
||||
if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
|
||||
relocation, false))
|
||||
relocation, r_type,
|
||||
false))
|
||||
r = bfd_reloc_overflow;
|
||||
unresolved_reloc = false;
|
||||
break;
|
||||
|
14
ld/ChangeLog
14
ld/ChangeLog
@ -1,3 +1,17 @@
|
||||
2021-06-22 Nelson Chu <nelson.chu@sifive.com>
|
||||
|
||||
* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
|
||||
* testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d: New testcase.
|
||||
* testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s: Likewise.
|
||||
* testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d: New testcase.
|
||||
Should report error since the %pcrel_lo with addend refers to
|
||||
%got_pcrel_hi.
|
||||
* testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s: Likewise.
|
||||
* testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d: New testcase.
|
||||
Should report error since the %got_pcrel_hi with addend.
|
||||
* testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s: Likewise.
|
||||
* testsuite/ld-riscv-elf/pcrel-lo-addend-3.ld: Likewise.
|
||||
|
||||
2021-06-19 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/27998
|
||||
|
@ -87,6 +87,9 @@ if [istarget "riscv*-*-*"] {
|
||||
run_dump_test "pcrel-lo-addend"
|
||||
run_dump_test "pcrel-lo-addend-2a"
|
||||
run_dump_test "pcrel-lo-addend-2b"
|
||||
run_dump_test "pcrel-lo-addend-3a"
|
||||
run_dump_test "pcrel-lo-addend-3b"
|
||||
run_dump_test "pcrel-lo-addend-3c"
|
||||
run_dump_test "restart-relax"
|
||||
run_dump_test "attr-merge-arch-01"
|
||||
run_dump_test "attr-merge-arch-02"
|
||||
|
13
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3.ld
Normal file
13
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3.ld
Normal file
@ -0,0 +1,13 @@
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
.got 0x1000 : {
|
||||
*(.got)
|
||||
}
|
||||
.data 0x2000: {
|
||||
*(.data)
|
||||
}
|
||||
.text 0x900000000 : {
|
||||
*(.text)
|
||||
}
|
||||
}
|
18
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d
Normal file
18
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.d
Normal file
@ -0,0 +1,18 @@
|
||||
#source: pcrel-lo-addend-3a.s
|
||||
#as: -march=rv64i -mabi=lp64 -mno-relax
|
||||
#ld: -m[riscv_choose_lp64_emul] -Tpcrel-lo-addend-3.ld
|
||||
#objdump: -d
|
||||
|
||||
#...
|
||||
Disassembly of section .text:
|
||||
|
||||
0+900000000 <_start>:
|
||||
.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,0x2
|
||||
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,0\(a5\) # 2000 <ll>
|
||||
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,4\(a5\)
|
||||
.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,0x2
|
||||
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,4\(a5\) # 2004 <ll\+0x4>
|
||||
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,8\(a5\)
|
||||
.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,0x1
|
||||
.*:[ ]+[0-9a-f]+[ ]+ld[ ]+a0,8\(a5\) # 1008 <_GLOBAL_OFFSET_TABLE_\+0x8>
|
||||
#pass
|
21
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s
Normal file
21
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3a.s
Normal file
@ -0,0 +1,21 @@
|
||||
.text
|
||||
.globl _start
|
||||
.align 3
|
||||
_start:
|
||||
.LA0: auipc a5, %pcrel_hi (ll)
|
||||
ld a0, %pcrel_lo (.LA0)(a5)
|
||||
ld a0, %pcrel_lo (.LA0 + 0x4)(a5)
|
||||
|
||||
.LA1: auipc a5, %pcrel_hi (ll + 0x4)
|
||||
ld a0, %pcrel_lo (.LA1)(a5)
|
||||
ld a0, %pcrel_lo (.LA1 + 0x4)(a5)
|
||||
|
||||
.LA2: auipc a5, %got_pcrel_hi (ll)
|
||||
ld a0, %pcrel_lo (.LA2)(a5)
|
||||
|
||||
.globl ll
|
||||
.data
|
||||
ll:
|
||||
.dword 0
|
||||
.dword 0
|
||||
.dword 0
|
4
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d
Normal file
4
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.d
Normal file
@ -0,0 +1,4 @@
|
||||
#source: pcrel-lo-addend-3b.s
|
||||
#as: -march=rv64i -mabi=lp64 -mno-relax
|
||||
#ld: -m[riscv_choose_lp64_emul] -Tpcrel-lo-addend-3.ld
|
||||
#error: .*dangerous relocation: The addend isn't allowed for R_RISCV_GOT_HI20
|
13
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s
Normal file
13
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3b.s
Normal file
@ -0,0 +1,13 @@
|
||||
.text
|
||||
.globl _start
|
||||
.align 3
|
||||
_start:
|
||||
.LA0: auipc a5, %got_pcrel_hi (ll + 0x4)
|
||||
ld a0, %pcrel_lo (.LA0)(a5)
|
||||
|
||||
.globl ll
|
||||
.data
|
||||
ll:
|
||||
.dword 0
|
||||
.dword 0
|
||||
.dword 0
|
4
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d
Normal file
4
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.d
Normal file
@ -0,0 +1,4 @@
|
||||
#source: pcrel-lo-addend-3c.s
|
||||
#as: -march=rv64i -mabi=lp64 -mno-relax
|
||||
#ld: -m[riscv_choose_lp64_emul] -Tpcrel-lo-addend-3.ld
|
||||
#error: .*dangerous relocation: %pcrel_lo with addend isn't allowed for R_RISCV_GOT_HI20
|
13
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s
Normal file
13
ld/testsuite/ld-riscv-elf/pcrel-lo-addend-3c.s
Normal file
@ -0,0 +1,13 @@
|
||||
.text
|
||||
.globl _start
|
||||
.align 3
|
||||
_start:
|
||||
.LA0: auipc a5, %got_pcrel_hi (ll)
|
||||
ld a0, %pcrel_lo (.LA0 + 0x4)(a5)
|
||||
|
||||
.globl ll
|
||||
.data
|
||||
ll:
|
||||
.dword 0
|
||||
.dword 0
|
||||
.dword 0
|
Loading…
x
Reference in New Issue
Block a user