aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authormengqinggang <mengqinggang@loongson.cn>2024-01-24 14:34:26 +0800
committerliuzhensong <liuzhensong@loongson.cn>2024-03-31 14:21:00 +0800
commitdaeda14191c1710ce967259a47ef4e0a3fb6eebf (patch)
treed812149875b5903fde600bb0e71a17f112b81df2 /bfd
parentc7a5bea4c62f286df830418de694821c7617cccd (diff)
downloadgdb-daeda14191c1710ce967259a47ef4e0a3fb6eebf.zip
gdb-daeda14191c1710ce967259a47ef4e0a3fb6eebf.tar.gz
gdb-daeda14191c1710ce967259a47ef4e0a3fb6eebf.tar.bz2
BFD: Fix the bug of R_LARCH_AGLIN caused by discard section
To represent the first and third expression of .align, R_LARCH_ALIGN need to associate with a symbol. We define a local symbol for R_LARCH_AGLIN. But if the section of the local symbol is discarded, it may result in a undefined symbol error. Instead, we use the section name symbols, and this does not need to add extra symbols. During partial linking (ld -r), if the symbol associated with a relocation is STT_SECTION type, the addend of relocation needs to add the section output offset. We prevent it for R_LARCH_ALIGN. The elf_backend_data.rela_normal only can set all relocations of a target to rela_normal. Add a new function is_rela_normal to elf_backend_data, it can set part of relocations to rela_normal.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/elf-bfd.h4
-rw-r--r--bfd/elflink.c5
-rw-r--r--bfd/elfnn-loongarch.c16
-rw-r--r--bfd/elfxx-target.h5
4 files changed, 29 insertions, 1 deletions
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index c5d3254..af507b9 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1721,6 +1721,10 @@ struct elf_backend_data
backend relocate_section routine for relocatable linking. */
unsigned rela_normal : 1;
+ /* Whether a relocation is rela_normal. Compared with rela_normal,
+ is_rela_normal can set part of relocations to rela_normal. */
+ bool (*is_rela_normal) (Elf_Internal_Rela *);
+
/* Set if DT_REL/DT_RELA/DT_RELSZ/DT_RELASZ should not include PLT
relocations. */
unsigned dtrel_excludes_plt : 1;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 24eb30d..5d9b409 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11692,7 +11692,10 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
{
rel_hash = PTR_ADD (esdo->rela.hashes, esdo->rela.count);
rela_hash_list = rel_hash;
- rela_normal = bed->rela_normal;
+ if (bed->is_rela_normal != NULL)
+ rela_normal = bed->is_rela_normal (irela);
+ else
+ rela_normal = bed->rela_normal;
}
irela->r_offset = _bfd_elf_section_offset (output_bfd,
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index c42052f..1679aa5 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -5454,6 +5454,21 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
return _bfd_elf_hash_symbol (h);
}
+/* If a relocation is rela_normal and the symbol associated with the
+ relocation is STT_SECTION type, the addend of the relocation would add
+ sec->output_offset when partial linking (ld -r).
+ See elf_backend_data.rela_normal and elf_link_input_bfd().
+ The addend of R_LARCH_ALIGN is used to represent the first and third
+ expression of .align, it should be a constant when linking. */
+
+static bool
+loongarch_elf_is_rela_normal (Elf_Internal_Rela *rel)
+{
+ if (R_LARCH_ALIGN == ELFNN_R_TYPE (rel->r_info))
+ return false;
+ return true;
+}
+
#define TARGET_LITTLE_SYM loongarch_elfNN_vec
#define TARGET_LITTLE_NAME "elfNN-loongarch"
#define ELF_ARCH bfd_arch_loongarch
@@ -5489,6 +5504,7 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
#define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
+#define elf_backend_is_rela_normal loongarch_elf_is_rela_normal
#define elf_backend_dtrel_excludes_plt 1
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 1e6992b..6e2d948 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -709,6 +709,10 @@
#define elf_backend_rela_normal 0
#endif
+#ifndef elf_backend_is_rela_normal
+#define elf_backend_is_rela_normal NULL
+#endif
+
#ifndef elf_backend_dtrel_excludes_plt
#define elf_backend_dtrel_excludes_plt 0
#endif
@@ -955,6 +959,7 @@ static const struct elf_backend_data elfNN_bed =
elf_backend_default_use_rela_p,
elf_backend_rela_plts_and_copies_p,
elf_backend_rela_normal,
+ elf_backend_is_rela_normal,
elf_backend_dtrel_excludes_plt,
elf_backend_sign_extend_vma,
elf_backend_want_got_plt,