From 5f4fa40e4def33ed428b2d72aeb2bf24b50a664e Mon Sep 17 00:00:00 2001 From: mengqinggang Date: Wed, 29 May 2024 14:50:39 +0800 Subject: LoongArch: Make align symbol be in same section with alignment directive R_LARCH_ALIGN (psABI v2.30) requires a symbol index. 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. Search it in its own section. Remove elf_backend_data.is_rela_normal() function added at commit daeda14191c. Co-authored-by: Jinyang He Reported-by: WANG Xuerui Link: https://lore.kernel.org/loongarch/2abbb633-a10e-71cc-a5e1-4d9e39074066@loongson.cn/T/#t --- gas/config/tc-loongarch.c | 63 +++++++++++++++++++++++++++++- gas/config/tc-loongarch.h | 3 ++ gas/testsuite/gas/loongarch/relax-align2.d | 24 ++++++++++++ gas/testsuite/gas/loongarch/relax-align2.s | 11 ++++++ gas/testsuite/gas/loongarch/relax_align.d | 6 +-- 5 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 gas/testsuite/gas/loongarch/relax-align2.d create mode 100644 gas/testsuite/gas/loongarch/relax-align2.s (limited to 'gas') diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index 00b8c80..e7de9d8 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 f53e358..20434ac 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 0000000..cbef84f --- /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 0000000..6cd6bd8 --- /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 acd215a..fc1fd03 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 -- cgit v1.1