From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 80126 invoked by alias); 10 Dec 2019 05:43:15 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 80115 invoked by uid 89); 10 Dec 2019 05:43:14 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-14.5 required=5.0 tests=AWL,BAYES_00,BODY_8BITS,FREEMAIL_FROM,GARBLED_BODY,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.1 spammy=D*@, 20191125, 2019-11-25, Presumably X-HELO: mail-oi1-f196.google.com Received: from mail-oi1-f196.google.com (HELO mail-oi1-f196.google.com) (209.85.167.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 10 Dec 2019 05:43:10 +0000 Received: by mail-oi1-f196.google.com with SMTP id a67so8726069oib.6 for ; Mon, 09 Dec 2019 21:43:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=U4EHrzNi5rqWFtagNkKS9JmqgRL8EAWgB3pQV9kGqLk=; b=QYGs7AO1qauOW9Qj0aPCbeGZ6Keqw511tGq9Kn7Xut1iY9lkM9TgMc96YmWCcuMAMR hbDvdD4uItCt6uUZImPezoKgsoEUxw8bxP85OQCJUBq8vOjTdef2R2jiig+h5aza1qMa 9ShApY68tIqnBMYyS8KLLs73UPWzplvPOMMuXAoAMKzrOyuRjRlVNiLkNB6yB45hQR9d O2uQTluIgn9+cnjW85ghB4szOvrTpK/XvEwdZTbB2VhDgjf+MiXpMpiYH8KmGcchO/hy gUxMPzX4XWL0xclMrx/8C/tQYnxd5+Vg+sn5+FIyIKoPdPTGPDAIShcJ7Pus3QKcdueT 8OAA== MIME-Version: 1.0 References: In-Reply-To: From: Kuan-Lin Chen Date: Tue, 10 Dec 2019 05:43:00 -0000 Message-ID: Subject: Re: [PATCH] [RISCV] Support subtraction of .uleb128. To: Palmer Dabbelt Cc: "binutils@sourceware.org Development" Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2019-12/txt/msg00132.txt.bz2 Hi Palmer, > GCC gives me -Wmaybe-uninitialized for both of these. May I know your gcc version? I tried gcc-7.3.0 and gcc-8.2.0, and I didn't get the warning. > I don't understand how this could possibly work: uleb128s can be long, so= we > can't just treat them as a single byte. Yes, uleb128s can be long so I implement riscv_elf_ignore_reloc to ignore the overflow checking. And I relocate uleb128s by myself in perform_relocation. > I'm having trouble testing it, though, > as I can't figure out how to emit R_RISCV_SET_ULEB128 alone. For example= , when > I try to insert a uleb128 in the assembler I'm not even getting a relocat= ion: .uleb128 only support subtract format. (.uleb128 .L1 - .L0) It is impossible to get final the value and the length for ".uleb128 symbol" in assemble-time. I think ".uleb128 symbol" is meaningless. Therefore, all targets just fill the value as assemble-time value without relocations. >I can get a R_RISCV_SUB_ULEB128, but it appears to be both producing the w= rong >value and garbaging up bytes after the relocation. For example: I get the same result in the object file but the different result in execut= able. pal.o: file format elf64-littleriscv Disassembly of section .text: 0000000000000000 <_start>: 0: 00000013 nop 0000000000000004 <.L0>: 4: 00000013 nop 0000000000000008 : 8: 00100013 li zero,1 c: aa04 fsd fs1,16(a2) c: R_RISCV_SET_ULEB128 .L1 c: R_RISCV_SUB_ULEB128 .L0 e: aaaa fsd fa0,336(sp) 10: 00200013 li zero,2 a.out: file format elf64-littleriscv Disassembly of section .text: 0000000000010078 <_start>: 10078: 00000013 nop 1007c: 00000013 nop 0000000000010080 : 10080: 00100013 li zero,1 10084: aa04 fsd fs1,16(a2) 10086: aaaa fsd fa0,336(sp) 10088: 00200013 li zero,2 Maybe there is something mismatched. But I don't have any idea currently. Could you please give me more information about your flow? Thanks. > Presumably that's why I can't get a _SET alone. I think it's meaningless to use _SET alone in assembly. > It looks like alignment is broken here after uleb128s, but it's not actua= lly > triggering an error in all cases. Having two of them in this test case d= oesn't > trigger the issue, but an odd number does. For example, the following so= urce I think this alignment issue can be fixed by the following patch: https://sourceware.org/ml/binutils/2019-12/msg00024.html Thanks for your review. Palmer Dabbelt =E6=96=BC 2019=E5=B9=B412=E6=9C= =887=E6=97=A5 =E9=80=B1=E5=85=AD =E4=B8=8A=E5=8D=887:47=E5=AF=AB=E9=81=93= =EF=BC=9A > > On Wed, 27 Nov 2019 00:11:50 PST (-0800), kuanlinchentw@gmail.com wrote: > > The data length of uleb128 is variable. So linker must recalculate the > > value of the subtraction. The patch leave relocations in object files > > so that linker can relocate again after relaxation. > > > > bfd/ChangeLog: > > * bfd-in2.h: Regenerated. > > * elfnn-riscv.c (write_uleb128): New function. > > (perform_relocation): Perform R_RISCV_SUB_ULEB128 and > > R_RISCV_SET_ULEB128 relocation. > > (riscv_elf_relocate_section): Likewise. > > * elfxx-riscv.c (howto_table): Add R_RISCV_SUB_ULEB128 and > > R_RISCV_SET_ULEB128. > > (riscv_elf_ignore_reloc): New function. > > * libbfd.h: Regenerated. > > * reloc.c (BFD_RELOC_RISCV_SET_ULEB128, BFD_RELOC_RISCV_SUB_ULEB128): > > New relocations to support .uleb128. > > > > gas/ChangeLog: > > * config/tc-riscv.c (md_apply_fix): Add BFD_RELOC_RISCV_SET_ULEB128 and > > BFD_RELOC_RISCV_SUB_ULEB128. > > (riscv_insert_uleb128_fixes): New function. > > (riscv_md_end): Scan rs_leb128 fragments. > > (riscv_pseudo_table): Remove uleb128. > > > > include/ChangeLog: > > * elf/riscv.h ((R_RISCV_SET_ULEB128, (R_RISCV_SUB_ULEB128): Define. > > > > ld/ChangeLog: > > * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Add uleb128. > > * testsuite/ld-riscv-elf/uleb128.d: New test. > > * testsuite/ld-riscv-elf/uleb128.s: New file. > > > > OK to commit? > > I'm having a lot of trouble trying to figure out how this works. LMK if = I'm > missing something, there's some comments in line: > > > From 9f7f0aaa484dee2b32c550f8cca4de18959f01e1 Mon Sep 17 00:00:00 2001 > > From: Kuan-Lin Chen > > Date: Thu, 14 Nov 2019 14:24:22 +0800 > > Subject: [PATCH] RISC-V: Support subtraction of .uleb128. > > > > The data length of uleb128 is variable. So linker must recalculate the > > value of the subtraction. The patch leave relocations in object files > > so that linker can relocate again after relaxation. > > > > bfd/ChangeLog: > > * bfd-in2.h: Regenerated. > > * elfnn-riscv.c (write_uleb128): New function. > > (perform_relocation): Perform R_RISCV_SUB_ULEB128 and > > R_RISCV_SET_ULEB128 relocation. > > (riscv_elf_relocate_section): Likewise. > > * elfxx-riscv.c (howto_table): Add R_RISCV_SUB_ULEB128 and > > R_RISCV_SET_ULEB128. > > (riscv_elf_ignore_reloc): New function. > > * libbfd.h: Regenerated. > > * reloc.c (BFD_RELOC_RISCV_SET_ULEB128, BFD_RELOC_RISCV_SUB_ULE= B128): > > New relocations to support .uleb128. > > > > gas/ChangeLog: > > * config/tc-riscv.c (md_apply_fix): Add BFD_RELOC_RISCV_SET_ULE= B128 and > > BFD_RELOC_RISCV_SUB_ULEB128. > > (riscv_insert_uleb128_fixes): New function. > > (riscv_md_end): Scan rs_leb128 fragments. > > (riscv_pseudo_table): Remove uleb128. > > > > include/ChangeLog: > > * elf/riscv.h ((R_RISCV_SET_ULEB128, (R_RISCV_SUB_ULEB128): Def= ine. > > > > ld/ChangeLog: > > * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Add uleb128. > > * testsuite/ld-riscv-elf/uleb128.d: New test. > > * testsuite/ld-riscv-elf/uleb128.s: New file. > > --- > > bfd/ChangeLog | 14 ++++ > > bfd/bfd-in2.h | 2 + > > bfd/elfnn-riscv.c | 82 ++++++++++++++++++++++ > > bfd/elfxx-riscv.c | 51 ++++++++++++++ > > bfd/libbfd.h | 2 + > > bfd/reloc.c | 4 ++ > > gas/ChangeLog | 8 +++ > > gas/config/tc-riscv.c | 47 ++++++++++++- > > include/ChangeLog | 4 ++ > > include/elf/riscv.h | 2 + > > ld/ChangeLog | 6 ++ > > ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 1 + > > ld/testsuite/ld-riscv-elf/uleb128.d | 18 +++++ > > ld/testsuite/ld-riscv-elf/uleb128.s | 18 +++++ > > 14 files changed, 258 insertions(+), 1 deletion(-) > > create mode 100644 ld/testsuite/ld-riscv-elf/uleb128.d > > create mode 100644 ld/testsuite/ld-riscv-elf/uleb128.s > > > > diff --git a/bfd/ChangeLog b/bfd/ChangeLog > > index 4a0852e577..d11ffde74c 100644 > > --- a/bfd/ChangeLog > > +++ b/bfd/ChangeLog > > @@ -1,3 +1,17 @@ > > +2019-11-27 Kuan-Lin Chen > > + > > + * bfd-in2.h: Regenerated. > > + * elfnn-riscv.c (write_uleb128): New function. > > + (perform_relocation): Perform R_RISCV_SUB_ULEB128 and > > + R_RISCV_SET_ULEB128 relocation. > > + (riscv_elf_relocate_section): Likewise. > > + * elfxx-riscv.c (howto_table): Add R_RISCV_SUB_ULEB128 and > > + R_RISCV_SET_ULEB128. > > + (riscv_elf_ignore_reloc): New function. > > + * libbfd.h: Regenerated. > > + * reloc.c (BFD_RELOC_RISCV_SET_ULEB128, BFD_RELOC_RISCV_SUB_UL= EB128): > > + New relocations to support .uleb128. > > + > > 2019-11-27 Alan Modra > > > > PR 23652 > > diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h > > index 44902fc8d0..a32708ebc2 100644 > > --- a/bfd/bfd-in2.h > > +++ b/bfd/bfd-in2.h > > @@ -4380,6 +4380,8 @@ number for the SBIC, SBIS, SBI and CBI instructio= ns */ > > BFD_RELOC_RISCV_SET16, > > BFD_RELOC_RISCV_SET32, > > BFD_RELOC_RISCV_32_PCREL, > > + BFD_RELOC_RISCV_SET_ULEB128, > > + BFD_RELOC_RISCV_SUB_ULEB128, > > > > /* Renesas RL78 Relocations. */ > > BFD_RELOC_RL78_NEG8, > > diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c > > index 997f786602..075ef6b82d 100644 > > --- a/bfd/elfnn-riscv.c > > +++ b/bfd/elfnn-riscv.c > > @@ -1419,6 +1419,26 @@ riscv_global_pointer_value (struct bfd_link_info= *info) > > return h->u.def.value + sec_addr (h->u.def.section); > > } > > > > +/* Write VAL in uleb128 format to P, returning a pointer to the > > + following byte. > > + This code is copied from elf-attr.c. */ > > + > > +static bfd_byte * > > +write_uleb128 (bfd_byte *p, unsigned int val) > > +{ > > + bfd_byte c; > > + do > > + { > > + c =3D val & 0x7f; > > + val >>=3D 7; > > + if (val) > > + c |=3D 0x80; > > + *(p++) =3D c; > > + } > > + while (val); > > + return p; > > +} > > + > > /* Emplace a static relocation. */ > > > > static bfd_reloc_status_type > > @@ -1512,6 +1532,25 @@ perform_relocation (const reloc_howto_type *howt= o, > > value =3D ENCODE_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value)); > > break; > > > > + case R_RISCV_SET_ULEB128: > > + case R_RISCV_SUB_ULEB128: > > + { > > + unsigned int len =3D 0; > > + bfd_byte *endp, *p; > > + > > + _bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset= , &len); > > + > > + /* Clean the contents value to zero. Do not reduce the length= . */ > > + p =3D contents + rel->r_offset; > > + endp =3D p + len -1; > > + memset (p, 0x80, len); > > + *(endp) =3D 0; > > + p =3D write_uleb128 (p, value) - 1; > > + if (p < endp) > > + *p |=3D 0x80; > > + return bfd_reloc_ok; > > + } > > + > > case R_RISCV_32: > > case R_RISCV_64: > > case R_RISCV_ADD8: > > @@ -1767,6 +1806,8 @@ riscv_elf_relocate_section (bfd *output_bfd, > > struct elf_link_hash_entry **sym_hashes =3D elf_sym_hashes (input_bf= d); > > bfd_vma *local_got_offsets =3D elf_local_got_offsets (input_bfd); > > bfd_boolean absolute; > > + bfd_vma uleb128_vma; > > + Elf_Internal_Rela *uleb128_rel =3D NULL; > > > > if (!riscv_init_pcrel_relocs (&pcrel_relocs)) > > return FALSE; > > @@ -1871,6 +1912,47 @@ riscv_elf_relocate_section (bfd *output_bfd, > > case R_RISCV_DELETE: > > /* These require no special handling beyond perform_relocati= on. */ > > break; > > + case R_RISCV_SET_ULEB128: > > + if (!uleb128_rel) > > + { > > + /* Save the minuend to use later. */ > > + uleb128_vma =3D relocation; > > + uleb128_rel =3D rel; > > + continue; > > + } > > + else > > + { > > + if (uleb128_rel->r_offset !=3D rel->r_offset) > > + { > > + (*_bfd_error_handler) (_("%pB: relocation %s mismatc= hed. "), > > + input_bfd, howto->name); > > + bfd_set_error (bfd_error_bad_value); > > + } > > + relocation =3D relocation - uleb128_vma; > > + uleb128_rel =3D NULL; > > + break; > > + } > > + > > + case R_RISCV_SUB_ULEB128: > > + if (uleb128_rel) > > + { > > + if (uleb128_rel->r_offset !=3D rel->r_offset) > > + { > > + (*_bfd_error_handler) (_("%pB: relocation %s mismatc= hed. "), > > + input_bfd, howto->name); > > + bfd_set_error (bfd_error_bad_value); > > + } > > + relocation =3D uleb128_vma - relocation; > > GCC gives me -Wmaybe-uninitialized for both of these. > > > + uleb128_rel =3D NULL; > > + break; > > + } > > + else > > + { > > + /* Save the subtrahend to use later. */ > > + uleb128_vma =3D relocation; > > + uleb128_rel =3D rel; > > + continue; > > + } > > > > case R_RISCV_GOT_HI20: > > if (h !=3D NULL) > > diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c > > index 245717f70f..c136ba2207 100644 > > --- a/bfd/elfxx-riscv.c > > +++ b/bfd/elfxx-riscv.c > > @@ -38,6 +38,8 @@ > > relocations for the debug info. */ > > static bfd_reloc_status_type riscv_elf_add_sub_reloc > > (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); > > +static bfd_reloc_status_type riscv_elf_ignore_reloc > > + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); > > > > /* The relocation table used for SHT_RELA sections. */ > > > > @@ -855,8 +857,41 @@ static reloc_howto_type howto_table[] =3D > > 0, /* src_mask */ > > MINUS_ONE, /* dst_mask */ > > FALSE), /* pcrel_offset */ > > + > > + /* The length of unsigned-leb128 is variant, just assume the > > + size is one byte here. */ > > + HOWTO (R_RISCV_SET_ULEB128, /* type */ > > + 0, /* rightshift */ > > + 0, /* size */ > > + 0, /* bitsize */ > > + FALSE, /* pc_relative */ > > + 0, /* bitpos */ > > + complain_overflow_dont, /* complain_on_overflow */ > > + riscv_elf_ignore_reloc, /* special_function */ > > + "R_RISCV_SET_ULEB128", /* name */ > > + FALSE, /* partial_inplace */ > > + 0, /* src_mask */ > > + 0, /* dst_mask */ > > + FALSE), /* pcrel_offset */ > > I don't understand how this could possibly work: uleb128s can be long, so= we > can't just treat them as a single byte. I'm having trouble testing it, t= hough, > as I can't figure out how to emit R_RISCV_SET_ULEB128 alone. For example= , when > I try to insert a uleb128 in the assembler I'm not even getting a relocat= ion: > > .text > .globl _start > _start: > nop > .L0: > nop > .L1: > uleb_l0: > addi x0, x0, 1 > .uleb128 .L0 > # Manually fix up the alignment, as .align is broken. > .rept 3 > .byte 0xAA > .endr > addi x0, x0, 2 > > $ objdump -dr > test.o: file format elf64-littleriscv > > > Disassembly of section .text: > > 0000000000000000 <_start>: > 0: 00000013 nop > 4: 00000013 nop > > 0000000000000008 : > 8: 00100013 li zero,1 > c: aa04 fsd fs1,16(a2) > e: aaaa fsd fa0,336(sp) > 10: 00200013 li zero,2 > > so then when I link I'm just getting the wrong value entirely. > > test: file format elf64-littleriscv > > > Disassembly of section .text: > > 0000000000010078 <_start>: > 10078: 00000013 nop > 1007c: 00000013 nop > > 0000000000010080 : > 10080: 00100013 li zero,1 > 10084: aa04 fsd fs1,16(a2) > 10086: aaaa fsd fa0,336(sp) > 10088: 00200013 li zero,2 > > > + /* The length of unsigned-leb128 is variant, just assume the > > + size is one byte here. */ > > + HOWTO (R_RISCV_SUB_ULEB128, /* type */ > > + 0, /* rightshift */ > > + 0, /* size */ > > + 0, /* bitsize */ > > + FALSE, /* pc_relative */ > > + 0, /* bitpos */ > > + complain_overflow_dont, /* complain_on_overflow */ > > + riscv_elf_ignore_reloc, /* special_function */ > > + "R_RISCV_SUB_ULEB128", /* name */ > > + FALSE, /* partial_inplace */ > > + 0, /* src_mask */ > > + 0, /* dst_mask */ > > + FALSE), /* pcrel_offset */ > > }; > > I can get a R_RISCV_SUB_ULEB128, but it appears to be both producing the = wrong > value and garbaging up bytes after the relocation. For example: > > .text > .globl _start > _start: > nop > .L0: > nop > .L1: > uleb_l1_l0: > addi x0, x0, 1 > .uleb128 .L1 - .L0 > # Manually fix up the alignment, as .align is broken > .rept 3 > .byte 0xAA > .endr > addi x0, x0, 2 > > produces the relocation > > test.o: file format elf64-littleriscv > > > Disassembly of section .text: > > 0000000000000000 <_start>: > 0: 00000013 nop > > 0000000000000004 <.L0>: > 4: 00000013 nop > > 0000000000000008 : > 8: 00100013 li zero,1 > c: aa04 fsd fs1,16(a2) > c: R_RISCV_SET_ULEB128 .L1 > c: R_RISCV_SUB_ULEB128 .L0 > e: aaaa fsd fa0,336(sp) > 10: 00200013 li zero,2 > > but then goes and corrupts the resulting executable > > > test: file format elf64-littleriscv > Disassembly of section .text: > > 0000000000010078 <_start>: > 10078: 00000013 nop > 1007c: 00000013 nop > > 0000000000010080 : > 10080: 00100013 li zero,1 > 10084: ff84 sd s1,56(a5) > 10086: 000ffffb 0xffffb > 1008a: 0020 addi s0,sp,8 > > I can't think of a way to make this work aside from just emitting uleb128= s at > their full length, which would make them work but would really defeat the > purpose of the format. I guess we could then relax these, but that seems= like > a lot of work. > > > + > > /* A mapping from BFD reloc types to RISC-V ELF reloc types. */ > > > > struct elf_reloc_map > > @@ -917,6 +952,8 @@ static const struct elf_reloc_map riscv_reloc_map[]= =3D > > { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 }, > > { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 }, > > { BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL }, > > + { BFD_RELOC_RISCV_SET_ULEB128, R_RISCV_SET_ULEB128 }, > > + { BFD_RELOC_RISCV_SUB_ULEB128, R_RISCV_SUB_ULEB128 }, > > }; > > > > /* Given a BFD reloc type, return a howto structure. */ > > @@ -1011,6 +1048,20 @@ riscv_elf_add_sub_reloc (bfd *abfd, > > return bfd_reloc_ok; > > } > > > > +/* Special handler for relocations which don't have to be relocated. > > + This function just simply return bfd_reloc_ok. */ > > +static bfd_reloc_status_type > > +riscv_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_ent= ry, > > + asymbol *symbol ATTRIBUTE_UNUSED, > > + void *data ATTRIBUTE_UNUSED, asection *input_s= ection, > > + bfd *output_bfd, char **error_message ATTRIBUT= E_UNUSED) > > +{ > > + if (output_bfd !=3D NULL) > > + reloc_entry->address +=3D input_section->output_offset; > > + > > + return bfd_reloc_ok; > > +} > > + > > /* Parsing subset version. > > > > Return Value: > > diff --git a/bfd/libbfd.h b/bfd/libbfd.h > > index 77b732ee4b..7aa8f91504 100644 > > --- a/bfd/libbfd.h > > +++ b/bfd/libbfd.h > > @@ -2327,6 +2327,8 @@ static const char *const bfd_reloc_code_real_name= s[] =3D { "@@uninitialized@@", > > "BFD_RELOC_RISCV_SET16", > > "BFD_RELOC_RISCV_SET32", > > "BFD_RELOC_RISCV_32_PCREL", > > + "BFD_RELOC_RISCV_SET_ULEB128", > > + "BFD_RELOC_RISCV_SUB_ULEB128", > > "BFD_RELOC_RL78_NEG8", > > "BFD_RELOC_RL78_NEG16", > > "BFD_RELOC_RL78_NEG24", > > diff --git a/bfd/reloc.c b/bfd/reloc.c > > index b00b79f319..9b8b75ad21 100644 > > --- a/bfd/reloc.c > > +++ b/bfd/reloc.c > > @@ -5212,6 +5212,10 @@ ENUMX > > BFD_RELOC_RISCV_SET32 > > ENUMX > > BFD_RELOC_RISCV_32_PCREL > > +ENUMX > > + BFD_RELOC_RISCV_SET_ULEB128 > > +ENUMX > > + BFD_RELOC_RISCV_SUB_ULEB128 > > ENUMDOC > > RISC-V relocations. > > > > diff --git a/gas/ChangeLog b/gas/ChangeLog > > index 09991524da..e53ac0895b 100644 > > --- a/gas/ChangeLog > > +++ b/gas/ChangeLog > > @@ -1,3 +1,11 @@ > > +2019-11-27 Kuan-Lin Chen > > + > > + * config/tc-riscv.c (md_apply_fix): Add BFD_RELOC_RISCV_SET_UL= EB128 and > > + BFD_RELOC_RISCV_SUB_ULEB128. > > + (riscv_insert_uleb128_fixes): New function. > > + (riscv_md_end): Scan rs_leb128 fragments. > > + (riscv_pseudo_table): Remove uleb128. > > + > > 2019-11-25 Andrew Pinski > > > > * config/tc-aarch64.c (md_begin): Use correct > > diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c > > index e50505138e..c35c591c0a 100644 > > --- a/gas/config/tc-riscv.c > > +++ b/gas/config/tc-riscv.c > > @@ -2392,6 +2392,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg = ATTRIBUTE_UNUSED) > > case BFD_RELOC_RISCV_SUB32: > > case BFD_RELOC_RISCV_SUB64: > > case BFD_RELOC_RISCV_RELAX: > > + /* cvt_frag_to_fill () has called output_leb128 (). */ > > + case BFD_RELOC_RISCV_SET_ULEB128: > > + case BFD_RELOC_RISCV_SUB_ULEB128: > > break; > > > > case BFD_RELOC_RISCV_TPREL_HI20: > > @@ -3127,11 +3130,54 @@ riscv_set_public_attributes (void) > > riscv_write_out_arch_attr (); > > } > > > > +/* Scan uleb128 subtraction expressions and insert fixups for them. > > + e.g., .uleb128 .L1 - .L0 > > + Becuase relaxation may change the value of the subtraction, we > > + must resolve them in link-time. */ > > + > > +static void > > +riscv_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED, > > + asection *sec, void *xxx ATTRIBUTE_UNUSED) > > +{ > > + segment_info_type *seginfo =3D seg_info (sec); > > + struct frag *fragP; > > + > > + subseg_set (sec, 0); > > + > > + for (fragP =3D seginfo->frchainP->frch_root; > > + fragP; fragP =3D fragP->fr_next) > > + { > > + expressionS *exp, *exp_dup; > > + > > + if (fragP->fr_type !=3D rs_leb128 || fragP->fr_symbol =3D=3D NU= LL) > > + continue; > > + > > + exp =3D symbol_get_value_expression (fragP->fr_symbol); > > + > > + if (exp->X_op !=3D O_subtract) > > + continue; > > Presumably that's why I can't get a _SET alone. > > > + > > + /* Only unsigned leb128 can be handle. */ > > + gas_assert (fragP->fr_subtype =3D=3D 0); > > + exp_dup =3D xmemdup (exp, sizeof (*exp), sizeof (*exp)); > > + exp_dup->X_op =3D O_symbol; > > + exp_dup->X_op_symbol =3D NULL; > > + > > + /* Insert relocations to resolve the subtraction in link-time. = */ > > + fix_new_exp (fragP, fragP->fr_fix, 0, > > + exp_dup, 0, BFD_RELOC_RISCV_SET_ULEB128); > > + exp_dup->X_add_symbol =3D exp->X_op_symbol; > > + fix_new_exp (fragP, fragP->fr_fix, 0, > > + exp_dup, 0, BFD_RELOC_RISCV_SUB_ULEB128); > > + } > > +} > > + > > /* Called after all assembly has been done. */ > > > > void > > riscv_md_end (void) > > { > > + bfd_map_over_sections (stdoutput, riscv_insert_uleb128_fixes, NULL); > > riscv_set_public_attributes (); > > } > > > > @@ -3215,7 +3261,6 @@ static const pseudo_typeS riscv_pseudo_table[] =3D > > {"dtprelword", s_dtprel, 4}, > > {"dtpreldword", s_dtprel, 8}, > > {"bss", s_bss, 0}, > > - {"uleb128", s_riscv_leb128, 0}, > > {"sleb128", s_riscv_leb128, 1}, > > {"insn", s_riscv_insn, 0}, > > {"attribute", s_riscv_attribute, 0}, > > diff --git a/include/ChangeLog b/include/ChangeLog > > index 47bb86cf71..c290b245c6 100644 > > --- a/include/ChangeLog > > +++ b/include/ChangeLog > > @@ -1,3 +1,7 @@ > > +2019-11-27 Kuan-Lin Chen > > + > > + * elf/riscv.h ((R_RISCV_SET_ULEB128, (R_RISCV_SUB_ULEB128): De= fine. > > + > > 2019-11-25 Alan Modra > > > > * coff/ti.h (GET_SCNHDR_SIZE, PUT_SCNHDR_SIZE, GET_SCN_SCNLEN), > > diff --git a/include/elf/riscv.h b/include/elf/riscv.h > > index 2f98aa4a3e..030679b35f 100644 > > --- a/include/elf/riscv.h > > +++ b/include/elf/riscv.h > > @@ -88,6 +88,8 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type) > > RELOC_NUMBER (R_RISCV_SET16, 55) > > RELOC_NUMBER (R_RISCV_SET32, 56) > > RELOC_NUMBER (R_RISCV_32_PCREL, 57) > > + RELOC_NUMBER (R_RISCV_SET_ULEB128, 58) > > + RELOC_NUMBER (R_RISCV_SUB_ULEB128, 59) > > END_RELOC_NUMBERS (R_RISCV_max) > > > > /* Processor specific flags for the ELF header e_flags field. */ > > diff --git a/ld/ChangeLog b/ld/ChangeLog > > index 969ab78035..5c2e406101 100644 > > --- a/ld/ChangeLog > > +++ b/ld/ChangeLog > > @@ -1,3 +1,9 @@ > > +2019-11-27 Kuan-Lin Chen > > + > > + * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Add uleb128. > > + * testsuite/ld-riscv-elf/uleb128.d: New test. > > + * testsuite/ld-riscv-elf/uleb128.s: New file. > > + > > 2019-11-26 Martin Liska > > > > * scripttempl/arclinux.sc: Add .text.sorted.* which is sorted > > diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/= ld-riscv-elf/ld-riscv-elf.exp > > index 7aabbdd641..809e40f08d 100644 > > --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp > > +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp > > @@ -38,6 +38,7 @@ if [istarget "riscv*-*-*"] { > > run_dump_test "attr-merge-priv-spec" > > run_dump_test "attr-merge-arch-failed-01" > > run_dump_test "attr-merge-stack-align-failed" > > + run_dump_test "uleb128" > > run_ld_link_tests { > > { "Weak reference 32" "-T weakref.ld -melf32lriscv" "" > > "-march=3Drv32i -mabi=3Dilp32" {weakref32.s} > > diff --git a/ld/testsuite/ld-riscv-elf/uleb128.d b/ld/testsuite/ld-risc= v-elf/uleb128.d > > new file mode 100644 > > index 0000000000..a921478e98 > > --- /dev/null > > +++ b/ld/testsuite/ld-riscv-elf/uleb128.d > > @@ -0,0 +1,18 @@ > > +#source: uleb128.s > > +#as: -march=3Drv32ic > > +#ld: -melf32lriscv > > +#objdump: -d > > + > > +.*:[ ]+file format .* > > + > > +Disassembly of section .text: > > + > > +.* <_start>: > > +.*jal.* > > +.*jal.* > > +.*jal.* > > +.*jal.* > > +.*jal.* > > +.*jal.* > > +.*:[ ]+0e0c.* > > +#pass > > diff --git a/ld/testsuite/ld-riscv-elf/uleb128.s b/ld/testsuite/ld-risc= v-elf/uleb128.s > > new file mode 100644 > > index 0000000000..f7d23be163 > > --- /dev/null > > +++ b/ld/testsuite/ld-riscv-elf/uleb128.s > > @@ -0,0 +1,18 @@ > > +.text > > +.globl bar > > +.globl _start > > +.option rvc > > +.align 2 > > +_start: > > +.L0: > > + .rept 6 > > + call bar > > + .endr > > +.align 2 > > +.L1: > > + .uleb128 .L1 - .L0 > > + .uleb128 .L2 - .L0 > > +.L2: > > +.align 2 > > +bar: > > + nop > > It looks like alignment is broken here after uleb128s, but it's not actua= lly > triggering an error in all cases. Having two of them in this test case d= oesn't > trigger the issue, but an odd number does. For example, the following so= urce > > .text > .globl _start > .align 2 > _start: > .uleb128 _start > .align 2 > _end: > nop > > links _end to a misaligned symbol > > Disassembly of section .text: > > 0000000000010078 <_start>: > ... > > 0000000000010079 <_end>: > 10079: 00000013 nop > 1007d: 0000 unimp > ... > > I'm assuming that's because norvc assumes 4-byte alignment in text sectio= ns, so > it's just eliding the alingment directives. With RVC I do get an error m= essage > > .text > .globl _start > .option rvc > .align 2 > _start: > .uleb128 _start > .align 2 > _end: > nop > > ./install/bin/riscv64-unknown-linux-gnu-ld: test.o(.text+0x1): 3 byte= s required for alignment to 4-byte boundary, but only 2 present > ./install/bin/riscv64-unknown-linux-gnu-ld: can't relax section: bad = value > > --=20 Best regards, Kuan-Lin Chen. kuanlinchentw@gmail.com