From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7803) id 9017A3858D3C; Wed, 29 Mar 2023 23:58:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9017A3858D3C Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Nelson Chu To: bfd-cvs@sourceware.org Subject: [binutils-gdb] RISC-V: Extract the ld code which are too complicated, and may be reused. X-Act-Checkin: binutils-gdb X-Git-Author: Nelson Chu X-Git-Refname: refs/heads/master X-Git-Oldrev: 2fc3b8a4cb8439fc53975c4e70336d76e3ddc531 X-Git-Newrev: 23068b02d3a6743658110c7662178fdebbe2ac6a Message-Id: <20230329235833.9017A3858D3C@sourceware.org> Date: Wed, 29 Mar 2023 23:58:33 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Mar 2023 23:58:33 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D23068b02d3a6= 743658110c7662178fdebbe2ac6a commit 23068b02d3a6743658110c7662178fdebbe2ac6a Author: Nelson Chu Date: Sat Mar 25 08:41:11 2023 +0800 RISC-V: Extract the ld code which are too complicated, and may be reuse= d. =20 These types of codes are different for each target, I am not sure what = are the best for RISC-V, so extract them out may be more easy to compare what's= the difference. =20 bfd/ * elfnn-riscv.c (RISCV_NEED_DYNAMIC_RELOC): New defined. Extracted from riscv_elf_check_relocs, to see if dynamic reloc is needed for = the specific relocation. (RISCV_GENERATE_DYNAMIC_RELOC): New defined. Extracted from riscv_elf_relocate_section, to see if R_RISCV_32/64 need to generate dynamic relocation. (RISCV_COPY_INPUT_RELOC): New defined. Extracted from riscv_elf_relocate_section, to see if R_RISCV_32/64 need to copy it= slef tp output file. (RISCV_RESOLVED_LOCALLY): New defined. Extracted from riscv_elf_relocate_section, to see if R_RISCV_GOT_HI20 can be resol= ved locally. Diff: --- bfd/elfnn-riscv.c | 156 ++++++++++++++++++++++++++++----------------------= ---- 1 file changed, 82 insertions(+), 74 deletions(-) diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 1200e6b11b5..59e949a2cb5 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -38,6 +38,79 @@ #define CHAR_BIT 8 #endif =20 +/* True if dynamic relocation is needed. If we are creating a shared libr= ary, + and this is a reloc against a global symbol, or a non PC relative reloc + against a local symbol, then we need to copy the reloc into the shared + library. However, if we are linking with -Bsymbolic, we do not need to + copy a reloc against a global symbol which is defined in an object we a= re + including in the link (i.e., DEF_REGULAR is set). + + At this point we have not seen all the input files, so it is possible t= hat + DEF_REGULAR is not set now but will be set later (it is never cleared). + In case of a weak definition, DEF_REGULAR may be cleared later by a str= ong + definition in a shared library. We account for that possibility below = by + storing information in the relocs_copied field of the hash table entry. + A similar situation occurs when creating shared libraries and symbol + visibility changes render the symbol local. + + If on the other hand, we are creating an executable, we may need to keep + relocations for symbols satisfied by a dynamic library if we manage to + avoid copy relocs for the symbol. + + Generate dynamic pointer relocation against STT_GNU_IFUNC symbol in the + non-code section (R_RISCV_32/R_RISCV_64). */ +#define RISCV_NEED_DYNAMIC_RELOC(PCREL, INFO, H, SEC) \ + ((bfd_link_pic (INFO) \ + && ((SEC)->flags & SEC_ALLOC) !=3D 0 \ + && (!(PCREL) \ + || ((H) !=3D NULL \ + && (!(INFO)->symbolic \ + || (H)->root.type =3D=3D bfd_link_hash_defweak \ + || !(H)->def_regular)))) \ + || (!bfd_link_pic (INFO) \ + && ((SEC)->flags & SEC_ALLOC) !=3D 0 \ + && (H) !=3D NULL \ + && ((H)->root.type =3D=3D bfd_link_hash_defweak \ + || !(H)->def_regular)) \ + || (!bfd_link_pic (INFO) \ + && (H) !=3D NULL \ + && (H)->type =3D=3D STT_GNU_IFUNC \ + && ((SEC)->flags & SEC_CODE) =3D=3D 0)) + +/* True if dynamic relocation should be generated. */ +#define RISCV_GENERATE_DYNAMIC_RELOC(PCREL, INFO, H, RESOLVED_TO_ZERO) \ + ((bfd_link_pic (INFO) \ + && ((H) =3D=3D NULL \ + || (ELF_ST_VISIBILITY ((H)->other) =3D=3D STV_DEFAULT && !(RESOLVED_TO_ZE= RO)) \ + || (H)->root.type !=3D bfd_link_hash_undefweak) \ + && (!(PCREL) \ + || !SYMBOL_CALLS_LOCAL ((INFO), (H)))) \ + || (!bfd_link_pic (INFO) \ + && (H) !=3D NULL \ + && (H)->dynindx !=3D -1 \ + && !(H)->non_got_ref \ + && (((H)->def_dynamic && !(H)->def_regular) \ + || (H)->root.type =3D=3D bfd_link_hash_undefweak \ + || (H)->root.type =3D=3D bfd_link_hash_undefined))) + +/* True if this input relocation should be copied to output. H->dynindx + may be -1 if this symbol was marked to become local. */ +#define RISCV_COPY_INPUT_RELOC(INFO, H) \ + ((H) !=3D NULL \ + && (H)->dynindx !=3D -1 \ + && (!bfd_link_pic (INFO) \ + || !SYMBOLIC_BIND ((INFO), (H)) \ + || !(H)->def_regular)) + +/* True if 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. */ +#define RISCV_RESOLVED_LOCALLY(INFO, H) \ + (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (elf_hash_table (INFO)->dynamic_sectio= ns_created, \ + bfd_link_pic (INFO), (H)) \ + || (bfd_link_pic (INFO) \ + && SYMBOL_REFERENCES_LOCAL ((INFO), (H)))) + /* Internal relocations used exclusively by the relaxation pass. */ #define R_RISCV_DELETE (R_RISCV_max + 1) =20 @@ -835,48 +908,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_inf= o *info, } } =20 - /* If we are creating a shared library, and this is a reloc - against a global symbol, or a non PC relative reloc - against a local symbol, then we need to copy the reloc - into the shared library. However, if we are linking with - -Bsymbolic, we do not need to copy a reloc against a - global symbol which is defined in an object we are - including in the link (i.e., DEF_REGULAR is set). At - this point we have not seen all the input files, so it is - possible that DEF_REGULAR is not set now but will be set - later (it is never cleared). In case of a weak definition, - DEF_REGULAR may be cleared later by a strong definition in - a shared library. We account for that possibility below by - storing information in the relocs_copied field of the hash - table entry. A similar situation occurs when creating - shared libraries and symbol visibility changes render the - symbol local. - - If on the other hand, we are creating an executable, we - may need to keep relocations for symbols satisfied by a - dynamic library if we manage to avoid copy relocs for the - symbol. - - Generate dynamic pointer relocation against STT_GNU_IFUNC - symbol in the non-code section (R_RISCV_32/R_RISCV_64). */ - reloc_howto_type * r =3D riscv_elf_rtype_to_howto (abfd, r_type); - - if ((bfd_link_pic (info) - && (sec->flags & SEC_ALLOC) !=3D 0 - && ((r !=3D NULL && !r->pc_relative) - || (h !=3D NULL - && (!info->symbolic - || h->root.type =3D=3D bfd_link_hash_defweak - || !h->def_regular)))) - || (!bfd_link_pic (info) - && (sec->flags & SEC_ALLOC) !=3D 0 - && h !=3D NULL - && (h->root.type =3D=3D bfd_link_hash_defweak - || !h->def_regular)) - || (!bfd_link_pic (info) - && h !=3D NULL - && h->type =3D=3D STT_GNU_IFUNC - && (sec->flags & SEC_CODE) =3D=3D 0)) + reloc_howto_type *r =3D riscv_elf_rtype_to_howto (abfd, r_type); + if (RISCV_NEED_DYNAMIC_RELOC (r->pc_relative, info, h, sec)) { struct elf_dyn_relocs *p; struct elf_dyn_relocs **head; @@ -2329,23 +2362,14 @@ riscv_elf_relocate_section (bfd *output_bfd, case R_RISCV_GOT_HI20: if (h !=3D NULL) { - bool dyn, pic; - off =3D h->got.offset; BFD_ASSERT (off !=3D (bfd_vma) -1); - dyn =3D elf_hash_table (info)->dynamic_sections_created; - pic =3D bfd_link_pic (info); =20 - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, pic, h) - || (pic && SYMBOL_REFERENCES_LOCAL (info, h))) + if (RISCV_RESOLVED_LOCALLY (info, h)) { - /* 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 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. =20 When doing a dynamic link, we create a .rela.got @@ -2610,21 +2634,8 @@ riscv_elf_relocate_section (bfd *output_bfd, if ((input_section->flags & SEC_ALLOC) =3D=3D 0) break; =20 - if ((bfd_link_pic (info) - && (h =3D=3D NULL - || (ELF_ST_VISIBILITY (h->other) =3D=3D STV_DEFAULT - && !resolved_to_zero) - || h->root.type !=3D bfd_link_hash_undefweak) - && (!howto->pc_relative - || !SYMBOL_CALLS_LOCAL (info, h))) - || (!bfd_link_pic (info) - && h !=3D NULL - && h->dynindx !=3D -1 - && !h->non_got_ref - && ((h->def_dynamic - && !h->def_regular) - || h->root.type =3D=3D bfd_link_hash_undefweak - || h->root.type =3D=3D bfd_link_hash_undefined))) + if (RISCV_GENERATE_DYNAMIC_RELOC (howto->pc_relative, info, h, + resolved_to_zero)) { Elf_Internal_Rela outrel; asection *sreloc; @@ -2643,10 +2654,7 @@ riscv_elf_relocate_section (bfd *output_bfd, =20 if (skip_dynamic_relocation) memset (&outrel, 0, sizeof outrel); - else if (h !=3D NULL && h->dynindx !=3D -1 - && !(bfd_link_pic (info) - && SYMBOLIC_BIND (info, h) - && h->def_regular)) + else if (RISCV_COPY_INPUT_RELOC (info, h)) { outrel.r_info =3D ELFNN_R_INFO (h->dynindx, r_type); outrel.r_addend =3D rel->r_addend;