Projects
openEuler:24.03:SP1:Everything
binutils
_service:tar_scm:LoongArch-Fix-DT_RELR-and-rela...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:LoongArch-Fix-DT_RELR-and-relaxation-interaction.patch of Package binutils
From 9a78ebba126036f6ebdd15ffbe50ffbd8ccd84dd Mon Sep 17 00:00:00 2001 From: Xi Ruoyao <xry111@xry111.site> Date: Mon, 12 Aug 2024 18:23:47 +0800 Subject: [PATCH 108/123] LoongArch: Fix DT_RELR and relaxation interaction Due to the way BFD implements DT_RELR as a part of relaxation, if in a relax trip size_relative_relocs has changed the layout, when relax_section runs only the vma of the section being relaxed is guaranteed to be updated. Then bad thing can happen. For example, when linking an auxilary program _freeze_module in the Python 3.12.4 building system (with PGO + LTO), before sizing the .relr.dyn section, the vma of .text is 30560 and the vma of .rodata is 2350944; in the final executable the vma of .text is 36704 and the vma of .rodata is 2357024. The vma increase is expected because .relr.dyn is squashed somewhere before .text. But size_relative_relocs may see the state in which .text is at 36704 but .rodata "is" still at 2350944. Thus the distance between .text and .rodata can be under-estimated and overflowing R_LARCH_PCREL20_S2 reloc can be created. To avoid this issue, if size_relative_relocs is updating the size of .relr.dyn, just supress the normal relaxation in this relax trip. In this situation size_relative_relocs should have been demending the next relax trip, so the normal relaxation can happen in the next trip. I tried to make a reduced test case but failed. Signed-off-by: Xi Ruoyao <xry111@xry111.site> --- bfd/elfnn-loongarch.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 73eea0f9..0c499c47 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -121,6 +121,12 @@ struct loongarch_elf_link_hash_table /* Layout recomputation count. */ bfd_size_type relr_layout_iter; + + /* In BFD DT_RELR is implemented as a "relaxation." If in a relax trip + size_relative_relocs is updating the layout, relax_section may see + a partially updated state (some sections have vma updated but the + others do not), and it's unsafe to do the normal relaxation. */ + bool layout_mutating_for_relr; }; struct loongarch_elf_section_data @@ -2210,6 +2216,8 @@ loongarch_elf_size_relative_relocs (struct bfd_link_info *info, *need_layout = false; } } + + htab->layout_mutating_for_relr = *need_layout; return true; } @@ -5256,6 +5264,13 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, return true; struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); + + /* It may happen that some sections have updated vma but the others do + not. Go to the next relax trip (size_relative_relocs should have + been demending another relax trip anyway). */ + if (htab->layout_mutating_for_relr) + return true; + if (bfd_link_relocatable (info) || sec->sec_flg0 || (sec->flags & SEC_RELOC) == 0 -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2