diff options
author | mengqinggang <mengqinggang@loongson.cn> | 2024-01-24 14:34:26 +0800 |
---|---|---|
committer | liuzhensong <liuzhensong@loongson.cn> | 2024-03-31 14:21:00 +0800 |
commit | daeda14191c1710ce967259a47ef4e0a3fb6eebf (patch) | |
tree | d812149875b5903fde600bb0e71a17f112b81df2 /bfd | |
parent | c7a5bea4c62f286df830418de694821c7617cccd (diff) | |
download | gdb-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.h | 4 | ||||
-rw-r--r-- | bfd/elflink.c | 5 | ||||
-rw-r--r-- | bfd/elfnn-loongarch.c | 16 | ||||
-rw-r--r-- | bfd/elfxx-target.h | 5 |
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, |