diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 15a7156b3da..45d36a78976 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1727,10 +1727,6 @@ 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 6db6a9c0b47..cca0c67f960 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -11889,10 +11889,7 @@ 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; - if (bed->is_rela_normal != NULL) - rela_normal = bed->is_rela_normal (irela); - else - rela_normal = bed->rela_normal; + 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 e60bd4db51e..93c036f6a53 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -5528,21 +5528,6 @@ 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 @@ -5578,7 +5563,6 @@ loongarch_elf_is_rela_normal (Elf_Internal_Rela *rel) #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 6e9b3f8d0a3..075f1bdd433 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -709,10 +709,6 @@ #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 @@ -959,7 +955,6 @@ 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, diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index 00b8c80c3de..e7de9d86313 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -419,6 +419,55 @@ loongarch_target_format () return LARCH_opts.ase_lp64 ? "elf64-loongarch" : "elf32-loongarch"; } +typedef struct +{ + unsigned int sec_id; + symbolS *s; +} align_sec_sym; + +static htab_t align_hash; + +static hashval_t +align_sec_sym_hash (const void *entry) +{ + const align_sec_sym *e = entry; + return (hashval_t) (e->sec_id); +} + +static int +align_sec_sym_eq (const void *entry1, const void *entry2) +{ + const align_sec_sym *e1 = entry1, *e2 = entry2; + return e1->sec_id == e2->sec_id; +} + +/* Make align symbol be in same section with alignment directive. + If the symbol is only created at the first time to handle alignment + directive. This means that all other sections may use this symbol. + If the section of this symbol is discarded, there may be problems. */ + +static symbolS *get_align_symbol (segT sec) +{ + align_sec_sym search = { sec->id, NULL }; + align_sec_sym *pentry = htab_find (align_hash, &search); + if (pentry) + return pentry->s; + + /* If we not find the symbol in this section. Create and insert it. */ + symbolS *s = (symbolS *)local_symbol_make (".Lla-relax-align", sec, + &zero_address_frag, 0); + align_sec_sym entry = { sec->id, s }; + align_sec_sym **slot = (align_sec_sym **) htab_find_slot (align_hash, + &entry, INSERT); + if (slot == NULL) + return NULL; + *slot = (align_sec_sym *) xmalloc (sizeof (align_sec_sym)); + if (*slot == NULL) + return NULL; + **slot = entry; + return entry.s; +} + void md_begin () { @@ -440,11 +489,21 @@ md_begin () it->name, it->format, it->macro); } + align_hash = htab_create (10, align_sec_sym_hash, align_sec_sym_eq, free); + /* FIXME: expressionS use 'offsetT' as constant, * we want this is 64-bit type. */ assert (8 <= sizeof (offsetT)); } +/* Called just before the assembler exits. */ + +void +loongarch_md_end (void) +{ + htab_delete (align_hash); +} + unsigned long loongarch_mach (void) { @@ -1826,7 +1885,9 @@ loongarch_frag_align_code (int n, int max) if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype). */ if (align_max) { - s = symbol_find (now_seg->name); + s = get_align_symbol (now_seg); + if (!s) + as_fatal (_("internal error: cannot get align symbol")); addend = ALIGN_MAX_ADDEND (n, max); } diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h index f53e3584c7c..20434ac8a01 100644 --- a/gas/config/tc-loongarch.h +++ b/gas/config/tc-loongarch.h @@ -32,6 +32,9 @@ extern unsigned long loongarch_mach (void); #define WORKING_DOT_WORD 1 #define REPEAT_CONS_EXPRESSIONS +#define md_end loongarch_md_end +extern void loongarch_md_end (void); + /* Early than md_begin. */ #define md_after_parse_args loongarch_after_parse_args extern void loongarch_after_parse_args (void); diff --git a/gas/testsuite/gas/loongarch/relax-align2.d b/gas/testsuite/gas/loongarch/relax-align2.d new file mode 100644 index 00000000000..cbef84f8777 --- /dev/null +++ b/gas/testsuite/gas/loongarch/relax-align2.d @@ -0,0 +1,24 @@ +#as: --no-warn +#readelf: -rsW +#skip: loongarch32-*-* + +Relocation section '\.rela\.text' at offset .* contains 2 entries: +.* +0+04[ ]+0000000000000066[ ]+R_LARCH_ALIGN[ ]+c +0+14[ ]+0000000500000066[ ]+R_LARCH_ALIGN[ ]+0+[ ]+\.Lla-relax-align \+ 404 + +Relocation section '\.rela\.text2' at offset .* contains 2 entries: +.* +0+04[ ]+0000000000000066[ ]+R_LARCH_ALIGN[ ]+c +0+14[ ]+0000000600000066[ ]+R_LARCH_ALIGN[ ]+0+[ ]+\.Lla-relax-align \+ 404 + +Symbol table '\.symtab' contains .* entries: +#... +[ ]+.*:[ ]+0+[ ]+0[ ]+SECTION[ ]+LOCAL[ ]+DEFAULT[ ]+1[ ]+\.text +#... +[ ]+.*:[ ]+0+[ ]+0[ ]+SECTION[ ]+LOCAL[ ]+DEFAULT[ ]+5[ ]+\.text2 +#... +[ ]+.*:[ ]+0+[ ]+0[ ]+NOTYPE[ ]+LOCAL[ ]+DEFAULT[ ]+1[ ]+\.Lla-relax-align +#... +[ ]+.*:[ ]+0+[ ]+0[ ]+NOTYPE[ ]+LOCAL[ ]+DEFAULT[ ]+5[ ]+\.Lla-relax-align +#pass diff --git a/gas/testsuite/gas/loongarch/relax-align2.s b/gas/testsuite/gas/loongarch/relax-align2.s new file mode 100644 index 00000000000..6cd6bd8731b --- /dev/null +++ b/gas/testsuite/gas/loongarch/relax-align2.s @@ -0,0 +1,11 @@ +.section ".text", "ax" +nop +.align 4 +nop +.align 4, , 4 + +.section ".text2", "ax" +nop +.align 4 +nop +.align 4, , 4 diff --git a/gas/testsuite/gas/loongarch/relax_align.d b/gas/testsuite/gas/loongarch/relax_align.d index acd215a4abc..fc1fd032611 100644 --- a/gas/testsuite/gas/loongarch/relax_align.d +++ b/gas/testsuite/gas/loongarch/relax_align.d @@ -7,7 +7,7 @@ Disassembly of section .text: -[ ]*0000000000000000 <.text>: +[ ]*0000000000000000 <.Lla-relax-align>: [ ]+0:[ ]+4c000020[ ]+ret [ ]+4:[ ]+03400000[ ]+nop [ ]+4: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc @@ -20,12 +20,12 @@ Disassembly of section .text: [ ]+1c:[ ]+03400000[ ]+nop [ ]+20:[ ]+4c000020[ ]+ret [ ]+24:[ ]+03400000[ ]+nop -[ ]+24: R_LARCH_ALIGN[ ]+.text\+0x104 +[ ]+24: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0x104 [ ]+28:[ ]+03400000[ ]+nop [ ]+2c:[ ]+03400000[ ]+nop [ ]+30:[ ]+4c000020[ ]+ret [ ]+34:[ ]+03400000[ ]+nop -[ ]+34: R_LARCH_ALIGN[ ]+.text\+0xb04 +[ ]+34: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0xb04 [ ]+38:[ ]+03400000[ ]+nop [ ]+3c:[ ]+03400000[ ]+nop [ ]+40:[ ]+4c000020[ ]+ret