diff --git a/Add-lbt-lvz-support.patch b/Add-lbt-lvz-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..576739b145080748c182244a1645c324c3959eb5 --- /dev/null +++ b/Add-lbt-lvz-support.patch @@ -0,0 +1,672 @@ +From 346701dda6cbf3ec8ee68e6618086c68e6216072 Mon Sep 17 00:00:00 2001 +From: cailulu +Date: Tue, 7 Nov 2023 17:50:04 +0800 +Subject: [PATCH 4/5] Add lbt-lvz support. + +Change-Id: Ia58c31ffbd4b15d3dda1b63d7dcfaba4b6002a28 +--- + gas/config/tc-loongarch.c | 8 +- + gas/testsuite/gas/loongarch/lvz-lbt.d | 191 +++++++++++++++++++++++++ + gas/testsuite/gas/loongarch/lvz-lbt.s | 181 ++++++++++++++++++++++++ + include/opcode/loongarch.h | 6 + + opcodes/loongarch-dis.c | 2 + + opcodes/loongarch-opc.c | 194 ++++++++++++++++++++++++++ + 6 files changed, 581 insertions(+), 1 deletion(-) + create mode 100644 gas/testsuite/gas/loongarch/lvz-lbt.d + create mode 100644 gas/testsuite/gas/loongarch/lvz-lbt.s + +diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c +index 4135b0b1..331cfe50 100644 +--- a/gas/config/tc-loongarch.c ++++ b/gas/config/tc-loongarch.c +@@ -120,7 +120,11 @@ md_parse_option (int c, const char *arg) + break; + case OPTION_ABI: + if (strcasecmp (arg, "lp64") == 0) +- LARCH_opts.abi_is_lp64 = 1; ++ { ++ LARCH_opts.abi_is_lp64 = 1; ++ LARCH_opts.ase_lvz = 1; ++ LARCH_opts.ase_lbt = 1; ++ } + else if (strcasecmp (arg, "lp32") == 0) + LARCH_opts.abi_is_lp32 = 1; + else +@@ -204,6 +208,8 @@ loongarch_after_parse_args () + { + LARCH_opts.addrwidth_is_64 = 1; + LARCH_opts.rlen_is_64 = 1; ++ LARCH_opts.ase_lvz = 1; ++ LARCH_opts.ase_lbt = 1; + for (i = 0; i < ARRAY_SIZE (loongarch_r_lp64_name); i++) + hash_insert (r_htab, loongarch_r_lp64_name[i], (void *) (i + 1)); + for (i = 0; i < ARRAY_SIZE (loongarch_r_lp64_name1); i++) +diff --git a/gas/testsuite/gas/loongarch/lvz-lbt.d b/gas/testsuite/gas/loongarch/lvz-lbt.d +new file mode 100644 +index 00000000..3f097473 +--- /dev/null ++++ b/gas/testsuite/gas/loongarch/lvz-lbt.d +@@ -0,0 +1,191 @@ ++#as: ++#objdump: -dr ++#skip: loongarch32-*-* ++ ++.*:[ ]+file format .* ++ ++ ++Disassembly of section .text: ++ ++00000000.* <.text>: ++[ ]+0:[ ]+05000400[ ]+gcsrrd[ ]+\$r0,0x1 ++[ ]+4:[ ]+05000420[ ]+gcsrwr[ ]+\$r0,0x1 ++[ ]+8:[ ]+05000483[ ]+gcsrxchg[ ]+\$r3,\$r4,0x1 ++[ ]+c:[ ]+06482401[ ]+gtlbflush ++[ ]+10:[ ]+002b8001[ ]+hvcl[ ]+0x1 ++[ ]+14:[ ]+00000820[ ]+movgr2scr[ ]+\$scr0,\$r1 ++[ ]+18:[ ]+00000c20[ ]+movscr2gr[ ]+\$r0,\$scr1 ++[ ]+1c:[ ]+48006600[ ]+jiscr0[ ]+100\(0x64\) ++[ ]+20:[ ]+48006700[ ]+jiscr1[ ]+100\(0x64\) ++[ ]+24:[ ]+00290420[ ]+addu12i.w[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+28:[ ]+00298420[ ]+addu12i.d[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+2c:[ ]+00300820[ ]+adc.b[ ]+\$r0,\$r1,\$r2 ++[ ]+30:[ ]+00308820[ ]+adc.h[ ]+\$r0,\$r1,\$r2 ++[ ]+34:[ ]+00310820[ ]+adc.w[ ]+\$r0,\$r1,\$r2 ++[ ]+38:[ ]+00318820[ ]+adc.d[ ]+\$r0,\$r1,\$r2 ++[ ]+3c:[ ]+00320820[ ]+sbc.b[ ]+\$r0,\$r1,\$r2 ++[ ]+40:[ ]+00328820[ ]+sbc.h[ ]+\$r0,\$r1,\$r2 ++[ ]+44:[ ]+00330820[ ]+sbc.w[ ]+\$r0,\$r1,\$r2 ++[ ]+48:[ ]+00338820[ ]+sbc.d[ ]+\$r0,\$r1,\$r2 ++[ ]+4c:[ ]+001a0820[ ]+rotr.b[ ]+\$r0,\$r1,\$r2 ++[ ]+50:[ ]+001a8820[ ]+rotr.h[ ]+\$r0,\$r1,\$r2 ++[ ]+54:[ ]+004c2420[ ]+rotri.b[ ]+\$r0,\$r1,0x1 ++[ ]+58:[ ]+004c4420[ ]+rotri.h[ ]+\$r0,\$r1,0x1 ++[ ]+5c:[ ]+00340820[ ]+rcr.b[ ]+\$r0,\$r1,\$r2 ++[ ]+60:[ ]+00348820[ ]+rcr.h[ ]+\$r0,\$r1,\$r2 ++[ ]+64:[ ]+00350820[ ]+rcr.w[ ]+\$r0,\$r1,\$r2 ++[ ]+68:[ ]+00358820[ ]+rcr.d[ ]+\$r0,\$r1,\$r2 ++[ ]+6c:[ ]+00502420[ ]+rcri.b[ ]+\$r0,\$r1,0x1 ++[ ]+70:[ ]+00504420[ ]+rcri.h[ ]+\$r0,\$r1,0x1 ++[ ]+74:[ ]+00508420[ ]+rcri.w[ ]+\$r0,\$r1,0x1 ++[ ]+78:[ ]+00510420[ ]+rcri.d[ ]+\$r0,\$r1,0x1 ++[ ]+7c:[ ]+0114e420[ ]+fcvt.ud.d[ ]+\$f0,\$f1 ++[ ]+80:[ ]+0114e020[ ]+fcvt.ld.d[ ]+\$f0,\$f1 ++[ ]+84:[ ]+01150820[ ]+fcvt.d.ld[ ]+\$f0,\$f1,\$f2 ++[ ]+88:[ ]+2e800420[ ]+ldl.d[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+8c:[ ]+2e000420[ ]+ldl.w[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+90:[ ]+2e400420[ ]+ldr.w[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+94:[ ]+2ec00420[ ]+ldr.d[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+98:[ ]+2f000420[ ]+stl.w[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+9c:[ ]+2f800420[ ]+stl.d[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+a0:[ ]+2f400420[ ]+str.w[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+a4:[ ]+2fc00420[ ]+str.d[ ]+\$r0,\$r1,1\(0x1\) ++[ ]+a8:[ ]+003f040c[ ]+x86adc.b[ ]+\$r0,\$r1 ++[ ]+ac:[ ]+003f040d[ ]+x86adc.h[ ]+\$r0,\$r1 ++[ ]+b0:[ ]+003f040e[ ]+x86adc.w[ ]+\$r0,\$r1 ++[ ]+b4:[ ]+003f040f[ ]+x86adc.d[ ]+\$r0,\$r1 ++[ ]+b8:[ ]+003f0404[ ]+x86add.b[ ]+\$r0,\$r1 ++[ ]+bc:[ ]+003f0405[ ]+x86add.h[ ]+\$r0,\$r1 ++[ ]+c0:[ ]+003f0406[ ]+x86add.w[ ]+\$r0,\$r1 ++[ ]+c4:[ ]+003f0407[ ]+x86add.d[ ]+\$r0,\$r1 ++[ ]+c8:[ ]+003f0400[ ]+x86add.wu[ ]+\$r0,\$r1 ++[ ]+cc:[ ]+003f0401[ ]+x86add.du[ ]+\$r0,\$r1 ++[ ]+d0:[ ]+00008000[ ]+x86inc.b[ ]+\$r0 ++[ ]+d4:[ ]+00008001[ ]+x86inc.h[ ]+\$r0 ++[ ]+d8:[ ]+00008002[ ]+x86inc.w[ ]+\$r0 ++[ ]+dc:[ ]+00008003[ ]+x86inc.d[ ]+\$r0 ++[ ]+e0:[ ]+003f0410[ ]+x86sbc.b[ ]+\$r0,\$r1 ++[ ]+e4:[ ]+003f0411[ ]+x86sbc.h[ ]+\$r0,\$r1 ++[ ]+e8:[ ]+003f0412[ ]+x86sbc.w[ ]+\$r0,\$r1 ++[ ]+ec:[ ]+003f0413[ ]+x86sbc.d[ ]+\$r0,\$r1 ++[ ]+f0:[ ]+003f0408[ ]+x86sub.b[ ]+\$r0,\$r1 ++[ ]+f4:[ ]+003f0409[ ]+x86sub.h[ ]+\$r0,\$r1 ++[ ]+f8:[ ]+003f040a[ ]+x86sub.w[ ]+\$r0,\$r1 ++[ ]+fc:[ ]+003f040b[ ]+x86sub.d[ ]+\$r0,\$r1 ++[ ]+100:[ ]+003f0402[ ]+x86sub.wu[ ]+\$r0,\$r1 ++[ ]+104:[ ]+003f0403[ ]+x86sub.du[ ]+\$r0,\$r1 ++[ ]+108:[ ]+00008004[ ]+x86dec.b[ ]+\$r0 ++[ ]+10c:[ ]+00008005[ ]+x86dec.h[ ]+\$r0 ++[ ]+110:[ ]+00008006[ ]+x86dec.w[ ]+\$r0 ++[ ]+114:[ ]+00008007[ ]+x86dec.d[ ]+\$r0 ++[ ]+118:[ ]+003f8410[ ]+x86and.b[ ]+\$r0,\$r1 ++[ ]+11c:[ ]+003f8411[ ]+x86and.h[ ]+\$r0,\$r1 ++[ ]+120:[ ]+003f8412[ ]+x86and.w[ ]+\$r0,\$r1 ++[ ]+124:[ ]+003f8413[ ]+x86and.d[ ]+\$r0,\$r1 ++[ ]+128:[ ]+003f8414[ ]+x86or.b[ ]+\$r0,\$r1 ++[ ]+12c:[ ]+003f8415[ ]+x86or.h[ ]+\$r0,\$r1 ++[ ]+130:[ ]+003f8416[ ]+x86or.w[ ]+\$r0,\$r1 ++[ ]+134:[ ]+003f8417[ ]+x86or.d[ ]+\$r0,\$r1 ++[ ]+138:[ ]+003f8418[ ]+x86xor.b[ ]+\$r0,\$r1 ++[ ]+13c:[ ]+003f8419[ ]+x86xor.h[ ]+\$r0,\$r1 ++[ ]+140:[ ]+003f841a[ ]+x86xor.w[ ]+\$r0,\$r1 ++[ ]+144:[ ]+003f841b[ ]+x86xor.d[ ]+\$r0,\$r1 ++[ ]+148:[ ]+003e8400[ ]+x86mul.b[ ]+\$r0,\$r1 ++[ ]+14c:[ ]+003e8401[ ]+x86mul.h[ ]+\$r0,\$r1 ++[ ]+150:[ ]+003e8402[ ]+x86mul.w[ ]+\$r0,\$r1 ++[ ]+154:[ ]+003e8403[ ]+x86mul.d[ ]+\$r0,\$r1 ++[ ]+158:[ ]+003e8404[ ]+x86mul.bu[ ]+\$r0,\$r1 ++[ ]+15c:[ ]+003e8405[ ]+x86mul.hu[ ]+\$r0,\$r1 ++[ ]+160:[ ]+003e8406[ ]+x86mul.wu[ ]+\$r0,\$r1 ++[ ]+164:[ ]+003e8407[ ]+x86mul.du[ ]+\$r0,\$r1 ++[ ]+168:[ ]+003f840c[ ]+x86rcl.b[ ]+\$r0,\$r1 ++[ ]+16c:[ ]+003f840d[ ]+x86rcl.h[ ]+\$r0,\$r1 ++[ ]+170:[ ]+003f840e[ ]+x86rcl.w[ ]+\$r0,\$r1 ++[ ]+174:[ ]+003f840f[ ]+x86rcl.d[ ]+\$r0,\$r1 ++[ ]+178:[ ]+00542418[ ]+x86rcli.b[ ]+\$r0,0x1 ++[ ]+17c:[ ]+00544419[ ]+x86rcli.h[ ]+\$r0,0x1 ++[ ]+180:[ ]+0054841a[ ]+x86rcli.w[ ]+\$r0,0x1 ++[ ]+184:[ ]+0055041b[ ]+x86rcli.d[ ]+\$r0,0x1 ++[ ]+188:[ ]+003f8408[ ]+x86rcr.b[ ]+\$r0,\$r1 ++[ ]+18c:[ ]+003f8409[ ]+x86rcr.h[ ]+\$r0,\$r1 ++[ ]+190:[ ]+003f840a[ ]+x86rcr.w[ ]+\$r0,\$r1 ++[ ]+194:[ ]+003f840b[ ]+x86rcr.d[ ]+\$r0,\$r1 ++[ ]+198:[ ]+00542410[ ]+x86rcri.b[ ]+\$r0,0x1 ++[ ]+19c:[ ]+00544411[ ]+x86rcri.h[ ]+\$r0,0x1 ++[ ]+1a0:[ ]+00548412[ ]+x86rcri.w[ ]+\$r0,0x1 ++[ ]+1a4:[ ]+00550413[ ]+x86rcri.d[ ]+\$r0,0x1 ++[ ]+1a8:[ ]+003f8404[ ]+x86rotl.b[ ]+\$r0,\$r1 ++[ ]+1ac:[ ]+003f8405[ ]+x86rotl.h[ ]+\$r0,\$r1 ++[ ]+1b0:[ ]+003f8406[ ]+x86rotl.w[ ]+\$r0,\$r1 ++[ ]+1b4:[ ]+003f8407[ ]+x86rotl.d[ ]+\$r0,\$r1 ++[ ]+1b8:[ ]+00542414[ ]+x86rotli.b[ ]+\$r0,0x1 ++[ ]+1bc:[ ]+00544415[ ]+x86rotli.h[ ]+\$r0,0x1 ++[ ]+1c0:[ ]+00548416[ ]+x86rotli.w[ ]+\$r0,0x1 ++[ ]+1c4:[ ]+00550417[ ]+x86rotli.d[ ]+\$r0,0x1 ++[ ]+1c8:[ ]+003f8400[ ]+x86rotr.b[ ]+\$r0,\$r1 ++[ ]+1cc:[ ]+003f8401[ ]+x86rotr.h[ ]+\$r0,\$r1 ++[ ]+1d0:[ ]+003f8402[ ]+x86rotr.d[ ]+\$r0,\$r1 ++[ ]+1d4:[ ]+003f8403[ ]+x86rotr.w[ ]+\$r0,\$r1 ++[ ]+1d8:[ ]+0054240c[ ]+x86rotri.b[ ]+\$r0,0x1 ++[ ]+1dc:[ ]+0054440d[ ]+x86rotri.h[ ]+\$r0,0x1 ++[ ]+1e0:[ ]+0054840e[ ]+x86rotri.w[ ]+\$r0,0x1 ++[ ]+1e4:[ ]+0055040f[ ]+x86rotri.d[ ]+\$r0,0x1 ++[ ]+1e8:[ ]+003f0414[ ]+x86sll.b[ ]+\$r0,\$r1 ++[ ]+1ec:[ ]+003f0415[ ]+x86sll.h[ ]+\$r0,\$r1 ++[ ]+1f0:[ ]+003f0416[ ]+x86sll.w[ ]+\$r0,\$r1 ++[ ]+1f4:[ ]+003f0417[ ]+x86sll.d[ ]+\$r0,\$r1 ++[ ]+1f8:[ ]+00542400[ ]+x86slli.b[ ]+\$r0,0x1 ++[ ]+1fc:[ ]+00544401[ ]+x86slli.h[ ]+\$r0,0x1 ++[ ]+200:[ ]+00548402[ ]+x86slli.w[ ]+\$r0,0x1 ++[ ]+204:[ ]+00550403[ ]+x86slli.d[ ]+\$r0,0x1 ++[ ]+208:[ ]+003f0418[ ]+x86srl.b[ ]+\$r0,\$r1 ++[ ]+20c:[ ]+003f0419[ ]+x86srl.h[ ]+\$r0,\$r1 ++[ ]+210:[ ]+003f041a[ ]+x86srl.w[ ]+\$r0,\$r1 ++[ ]+214:[ ]+003f041b[ ]+x86srl.d[ ]+\$r0,\$r1 ++[ ]+218:[ ]+00542404[ ]+x86srli.b[ ]+\$r0,0x1 ++[ ]+21c:[ ]+00544405[ ]+x86srli.h[ ]+\$r0,0x1 ++[ ]+220:[ ]+00548406[ ]+x86srli.w[ ]+\$r0,0x1 ++[ ]+224:[ ]+00550407[ ]+x86srli.d[ ]+\$r0,0x1 ++[ ]+228:[ ]+003f041c[ ]+x86sra.b[ ]+\$r0,\$r1 ++[ ]+22c:[ ]+003f041d[ ]+x86sra.h[ ]+\$r0,\$r1 ++[ ]+230:[ ]+003f041e[ ]+x86sra.w[ ]+\$r0,\$r1 ++[ ]+234:[ ]+003f041f[ ]+x86sra.d[ ]+\$r0,\$r1 ++[ ]+238:[ ]+00542408[ ]+x86srai.b[ ]+\$r0,0x1 ++[ ]+23c:[ ]+00544409[ ]+x86srai.h[ ]+\$r0,0x1 ++[ ]+240:[ ]+0054840a[ ]+x86srai.w[ ]+\$r0,0x1 ++[ ]+244:[ ]+0055040b[ ]+x86srai.d[ ]+\$r0,0x1 ++[ ]+248:[ ]+00368400[ ]+setx86j[ ]+\$r0,0x1 ++[ ]+24c:[ ]+00007820[ ]+setx86loope[ ]+\$r0,\$r1 ++[ ]+250:[ ]+00007c20[ ]+setx86loopne[ ]+\$r0,\$r1 ++[ ]+254:[ ]+005c0400[ ]+x86mfflag[ ]+\$r0,0x1 ++[ ]+258:[ ]+005c0420[ ]+x86mtflag[ ]+\$r0,0x1 ++[ ]+25c:[ ]+00007400[ ]+x86mftop[ ]+\$r0 ++[ ]+260:[ ]+00007020[ ]+x86mttop[ ]+0x1 ++[ ]+264:[ ]+00008009[ ]+x86inctop ++[ ]+268:[ ]+00008029[ ]+x86dectop ++[ ]+26c:[ ]+00008008[ ]+x86settm ++[ ]+270:[ ]+00008028[ ]+x86clrtm ++[ ]+274:[ ]+00580420[ ]+x86settag[ ]+\$r0,0x1,0x1 ++[ ]+278:[ ]+00370411[ ]+armadd.w[ ]+\$r0,\$r1,0x1 ++[ ]+27c:[ ]+00378411[ ]+armsub.w[ ]+\$r0,\$r1,0x1 ++[ ]+280:[ ]+00380411[ ]+armadc.w[ ]+\$r0,\$r1,0x1 ++[ ]+284:[ ]+00388411[ ]+armsbc.w[ ]+\$r0,\$r1,0x1 ++[ ]+288:[ ]+00390411[ ]+armand.w[ ]+\$r0,\$r1,0x1 ++[ ]+28c:[ ]+00398411[ ]+armor.w[ ]+\$r0,\$r1,0x1 ++[ ]+290:[ ]+003a0411[ ]+armxor.w[ ]+\$r0,\$r1,0x1 ++[ ]+294:[ ]+003fc41c[ ]+armnot.w[ ]+\$r0,0x1 ++[ ]+298:[ ]+003a8411[ ]+armsll.w[ ]+\$r0,\$r1,0x1 ++[ ]+29c:[ ]+003b0411[ ]+armsrl.w[ ]+\$r0,\$r1,0x1 ++[ ]+2a0:[ ]+003b8411[ ]+armsra.w[ ]+\$r0,\$r1,0x1 ++[ ]+2a4:[ ]+003c0411[ ]+armrotr.w[ ]+\$r0,\$r1,0x1 ++[ ]+2a8:[ ]+003c8411[ ]+armslli.w[ ]+\$r0,0x1,0x1 ++[ ]+2ac:[ ]+003d0411[ ]+armsrli.w[ ]+\$r0,0x1,0x1 ++[ ]+2b0:[ ]+003d8411[ ]+armsrai.w[ ]+\$r0,0x1,0x1 ++[ ]+2b4:[ ]+003e0411[ ]+armrotri.w[ ]+\$r0,0x1,0x1 ++[ ]+2b8:[ ]+003fc41f[ ]+armrrx.w[ ]+\$r0,0x1 ++[ ]+2bc:[ ]+00364420[ ]+armmove[ ]+\$r0,\$r1,0x1 ++[ ]+2c0:[ ]+003fc41d[ ]+armmov.w[ ]+\$r0,0x1 ++[ ]+2c4:[ ]+003fc41e[ ]+armmov.d[ ]+\$r0,0x1 ++[ ]+2c8:[ ]+005c0440[ ]+armmfflag[ ]+\$r0,0x1 ++[ ]+2cc:[ ]+005c0460[ ]+armmtflag[ ]+\$r0,0x1 ++[ ]+2d0:[ ]+0036c400[ ]+setarmj[ ]+\$r0,0x1 +diff --git a/gas/testsuite/gas/loongarch/lvz-lbt.s b/gas/testsuite/gas/loongarch/lvz-lbt.s +new file mode 100644 +index 00000000..850f77ff +--- /dev/null ++++ b/gas/testsuite/gas/loongarch/lvz-lbt.s +@@ -0,0 +1,181 @@ ++gcsrrd $r0, 1 ++gcsrwr $r0, 1 ++gcsrxchg $r3, $r4, 1 ++gtlbflush ++hvcl 1 ++movgr2scr $scr0, $r1 ++movscr2gr $r0, $scr1 ++jiscr0 100 ++jiscr1 100 ++addu12i.w $r0, $r1, 1 ++addu12i.d $r0, $r1, 1 ++adc.b $r0, $r1, $r2 ++adc.h $r0, $r1, $r2 ++adc.w $r0, $r1, $r2 ++adc.d $r0, $r1, $r2 ++sbc.b $r0, $r1, $r2 ++sbc.h $r0, $r1, $r2 ++sbc.w $r0, $r1, $r2 ++sbc.d $r0, $r1, $r2 ++rotr.b $r0, $r1, $r2 ++rotr.h $r0, $r1, $r2 ++rotri.b $r0, $r1, 1 ++rotri.h $r0, $r1, 1 ++rcr.b $r0, $r1, $r2 ++rcr.h $r0, $r1, $r2 ++rcr.w $r0, $r1, $r2 ++rcr.d $r0, $r1, $r2 ++rcri.b $r0, $r1, 1 ++rcri.h $r0, $r1, 1 ++rcri.w $r0, $r1, 1 ++rcri.d $r0, $r1, 1 ++fcvt.ud.d $f0, $f1 ++fcvt.ld.d $f0, $f1 ++fcvt.d.ld $f0, $f1, $f2 ++ldl.d $r0, $r1, 1 ++ldl.w $r0, $r1, 1 ++ldr.w $r0, $r1, 1 ++ldr.d $r0, $r1, 1 ++stl.w $r0, $r1, 1 ++stl.d $r0, $r1, 1 ++str.w $r0, $r1, 1 ++str.d $r0, $r1, 1 ++x86adc.b $r0, $r1 ++x86adc.h $r0, $r1 ++x86adc.w $r0, $r1 ++x86adc.d $r0, $r1 ++x86add.b $r0, $r1 ++x86add.h $r0, $r1 ++x86add.w $r0, $r1 ++x86add.d $r0, $r1 ++x86add.wu $r0, $r1 ++x86add.du $r0, $r1 ++x86inc.b $r0 ++x86inc.h $r0 ++x86inc.w $r0 ++x86inc.d $r0 ++x86sbc.b $r0, $r1 ++x86sbc.h $r0, $r1 ++x86sbc.w $r0, $r1 ++x86sbc.d $r0, $r1 ++x86sub.b $r0, $r1 ++x86sub.h $r0, $r1 ++x86sub.w $r0, $r1 ++x86sub.d $r0, $r1 ++x86sub.wu $r0, $r1 ++x86sub.du $r0, $r1 ++x86dec.b $r0 ++x86dec.h $r0 ++x86dec.w $r0 ++x86dec.d $r0 ++x86and.b $r0, $r1 ++x86and.h $r0, $r1 ++x86and.w $r0, $r1 ++x86and.d $r0, $r1 ++x86or.b $r0, $r1 ++x86or.h $r0, $r1 ++x86or.w $r0, $r1 ++x86or.d $r0, $r1 ++x86xor.b $r0, $r1 ++x86xor.h $r0, $r1 ++x86xor.w $r0, $r1 ++x86xor.d $r0, $r1 ++x86mul.b $r0, $r1 ++x86mul.h $r0, $r1 ++x86mul.w $r0, $r1 ++x86mul.d $r0, $r1 ++x86mul.bu $r0, $r1 ++x86mul.hu $r0, $r1 ++x86mul.wu $r0, $r1 ++x86mul.du $r0, $r1 ++x86rcl.b $r0, $r1 ++x86rcl.h $r0, $r1 ++x86rcl.w $r0, $r1 ++x86rcl.d $r0, $r1 ++x86rcli.b $r0, 1 ++x86rcli.h $r0, 1 ++x86rcli.w $r0, 1 ++x86rcli.d $r0, 1 ++x86rcr.b $r0, $r1 ++x86rcr.h $r0, $r1 ++x86rcr.w $r0, $r1 ++x86rcr.d $r0, $r1 ++x86rcri.b $r0, 1 ++x86rcri.h $r0, 1 ++x86rcri.w $r0, 1 ++x86rcri.d $r0, 1 ++x86rotl.b $r0, $r1 ++x86rotl.h $r0, $r1 ++x86rotl.w $r0, $r1 ++x86rotl.d $r0, $r1 ++x86rotli.b $r0, 1 ++x86rotli.h $r0, 1 ++x86rotli.w $r0, 1 ++x86rotli.d $r0, 1 ++x86rotr.b $r0, $r1 ++x86rotr.h $r0, $r1 ++x86rotr.d $r0, $r1 ++x86rotr.w $r0, $r1 ++x86rotri.b $r0, 1 ++x86rotri.h $r0, 1 ++x86rotri.w $r0, 1 ++x86rotri.d $r0, 1 ++x86sll.b $r0, $r1 ++x86sll.h $r0, $r1 ++x86sll.w $r0, $r1 ++x86sll.d $r0, $r1 ++x86slli.b $r0, 1 ++x86slli.h $r0, 1 ++x86slli.w $r0, 1 ++x86slli.d $r0, 1 ++x86srl.b $r0, $r1 ++x86srl.h $r0, $r1 ++x86srl.w $r0, $r1 ++x86srl.d $r0, $r1 ++x86srli.b $r0, 1 ++x86srli.h $r0, 1 ++x86srli.w $r0, 1 ++x86srli.d $r0, 1 ++x86sra.b $r0, $r1 ++x86sra.h $r0, $r1 ++x86sra.w $r0, $r1 ++x86sra.d $r0, $r1 ++x86srai.b $r0, 1 ++x86srai.h $r0, 1 ++x86srai.w $r0, 1 ++x86srai.d $r0, 1 ++setx86j $r0, 1 ++setx86loope $r0, $r1 ++setx86loopne $r0, $r1 ++x86mfflag $r0, 1 ++x86mtflag $r0, 1 ++x86mftop $r0 ++x86mttop 1 ++x86inctop ++x86dectop ++x86settm ++x86clrtm ++x86settag $r0, 1, 1 ++armadd.w $r0, $r1, 1 ++armsub.w $r0, $r1, 1 ++armadc.w $r0, $r1, 1 ++armsbc.w $r0, $r1, 1 ++armand.w $r0, $r1, 1 ++armor.w $r0, $r1, 1 ++armxor.w $r0, $r1, 1 ++armnot.w $r0, 1 ++armsll.w $r0, $r1, 1 ++armsrl.w $r0, $r1, 1 ++armsra.w $r0, $r1, 1 ++armrotr.w $r0, $r1, 1 ++armslli.w $r0, 1, 1 ++armsrli.w $r0, 1, 1 ++armsrai.w $r0, 1, 1 ++armrotri.w $r0, 1, 1 ++armrrx.w $r0, 1 ++armmove $r0, $r1, 1 ++armmov.w $r0, 1 ++armmov.d $r0, 1 ++armmfflag $r0, 1 ++armmtflag $r0, 1 ++setarmj $r0, 1 +diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h +index fc0be236..94973cbd 100644 +--- a/include/opcode/loongarch.h ++++ b/include/opcode/loongarch.h +@@ -204,6 +204,12 @@ extern struct loongarch_ASEs_option + + int abi_is_lp32; + int abi_is_lp64; ++ ++ int use_lvz; ++ int use_lbt; ++ ++#define ase_lvz use_lvz ++#define ase_lbt use_lbt + } LARCH_opts; + + extern size_t loongarch_insn_length (insn_t insn); +diff --git a/opcodes/loongarch-dis.c b/opcodes/loongarch-dis.c +index a159bb68..b34847be 100644 +--- a/opcodes/loongarch-dis.c ++++ b/opcodes/loongarch-dis.c +@@ -56,6 +56,8 @@ set_default_loongarch_dis_options (void) + LARCH_opts.ase_float = 1; + LARCH_opts.ase_128vec = 1; + LARCH_opts.ase_256vec = 1; ++ LARCH_opts.ase_lvz = 1; ++ LARCH_opts.ase_lbt = 1; + + loongarch_r_disname = loongarch_r_normal_name; + loongarch_f_disname = loongarch_f_normal_name; +diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c +index 21b0aff0..1e251e3d 100644 +--- a/opcodes/loongarch-opc.c ++++ b/opcodes/loongarch-opc.c +@@ -2257,6 +2257,198 @@ static struct loongarch_opcode loongarch_256vec_opcodes[] = { + + }; + ++static struct loongarch_opcode loongarch_lvz_opcodes[] = ++{ ++ /* match, mask, name, format, macro, include, exclude, pinfo. */ ++ {0x05000000, 0xff0003e0, "gcsrrd", "r0:5,u10:14", 0, 0, 0, 0}, ++ {0x05000020, 0xff0003e0, "gcsrwr", "r0:5,u10:14", 0, 0, 0, 0}, ++ {0x05000000, 0xff000000, "gcsrxchg", "r0:5,r5:5,u10:14", 0, 0, 0, 0}, ++ {0x06482401, 0xffffffff, "gtlbflush", "", 0, 0, 0, 0}, ++ {0x002b8000, 0xffff8000, "hvcl", "u0:15", 0, 0, 0, 0}, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list. */ ++}; ++ ++static struct loongarch_opcode loongarch_lbt_opcodes[] = ++{ ++ /* match, mask, name, format, macro, include, exclude, pinfo. */ ++ {0x00000800, 0xfffffc1c, "movgr2scr", "cr0:2,r5:5", 0, 0, 0, 0}, ++ {0x00000c00, 0xffffff80, "movscr2gr", "r0:5,cr5:2", 0, 0, 0, 0}, ++ {0x48000200, 0xfc0003e0, "jiscr0", "s0:5|10:16<<2", 0, 0, 0, 0}, ++ {0x48000300, 0xfc0003e0, "jiscr1", "s0:5|10:16<<2", 0, 0, 0, 0}, ++ {0x00290000, 0xffff8000, "addu12i.w", "r0:5,r5:5,s10:5", 0, 0, 0, 0}, ++ {0x00298000, 0xffff8000, "addu12i.d", "r0:5,r5:5,s10:5", 0, 0, 0, 0}, ++ {0x00300000, 0xffff8000, "adc.b", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00308000, 0xffff8000, "adc.h", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00310000, 0xffff8000, "adc.w", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00318000, 0xffff8000, "adc.d", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00320000, 0xffff8000, "sbc.b", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00328000, 0xffff8000, "sbc.h", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00330000, 0xffff8000, "sbc.w", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00338000, 0xffff8000, "sbc.d", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x001a0000, 0xffff8000, "rotr.b", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x001a8000, 0xffff8000, "rotr.h", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x004c2000, 0xffffe000, "rotri.b", "r0:5,r5:5,u10:3", 0, 0, 0, 0}, ++ {0x004c4000, 0xffffc000, "rotri.h", "r0:5,r5:5,u10:4", 0, 0, 0, 0}, ++ {0x00340000, 0xffff8000, "rcr.b", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00348000, 0xffff8000, "rcr.h", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00350000, 0xffff8000, "rcr.w", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00358000, 0xffff8000, "rcr.d", "r0:5,r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00502000, 0xffffe000, "rcri.b", "r0:5,r5:5,u10:3", 0, 0, 0, 0}, ++ {0x00504000, 0xffffc000, "rcri.h", "r0:5,r5:5,u10:4", 0, 0, 0, 0}, ++ {0x00508000, 0xffff8000, "rcri.w", "r0:5,r5:5,u10:5", 0, 0, 0, 0}, ++ {0x00510000, 0xffff0000, "rcri.d", "r0:5,r5:5,u10:6", 0, 0, 0, 0}, ++ {0x0114e400, 0xfffffc00, "fcvt.ud.d", "f0:5,f5:5", 0, 0, 0, 0}, ++ {0x0114e000, 0xfffffc00, "fcvt.ld.d", "f0:5,f5:5", 0, 0, 0, 0}, ++ {0x01150000, 0xffff8000, "fcvt.d.ld", "f0:5,f5:5,f10:5", 0, 0, 0, 0}, ++ {0x2e800000, 0xffc00000, "ldl.d", "r0:5,r5:5,so10:12", 0, 0, 0, 0}, ++ {0x2e000000, 0xffc00000, "ldl.w", "r0:5,r5:5,so10:12", 0, 0, 0, 0}, ++ {0x2e400000, 0xffc00000, "ldr.w", "r0:5,r5:5,so10:12", 0, 0, 0, 0}, ++ {0x2ec00000, 0xffc00000, "ldr.d", "r0:5,r5:5,so10:12", 0, 0, 0, 0}, ++ {0x2f000000, 0xffc00000, "stl.w", "r0:5,r5:5,so10:12", 0, 0, 0, 0}, ++ {0x2f800000, 0xffc00000, "stl.d", "r0:5,r5:5,so10:12", 0, 0, 0, 0}, ++ {0x2f400000, 0xffc00000, "str.w", "r0:5,r5:5,so10:12", 0, 0, 0, 0}, ++ {0x2fc00000, 0xffc00000, "str.d", "r0:5,r5:5,so10:12", 0, 0, 0, 0}, ++ {0x003f000c, 0xffff801f, "x86adc.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f000d, 0xffff801f, "x86adc.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f000e, 0xffff801f, "x86adc.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f000f, 0xffff801f, "x86adc.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0004, 0xffff801f, "x86add.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0005, 0xffff801f, "x86add.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0006, 0xffff801f, "x86add.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0007, 0xffff801f, "x86add.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0000, 0xffff801f, "x86add.wu", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0001, 0xffff801f, "x86add.du", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00008000, 0xfffffc1f, "x86inc.b", "r5:5", 0, 0, 0, 0}, ++ {0x00008001, 0xfffffc1f, "x86inc.h", "r5:5", 0, 0, 0, 0}, ++ {0x00008002, 0xfffffc1f, "x86inc.w", "r5:5", 0, 0, 0, 0}, ++ {0x00008003, 0xfffffc1f, "x86inc.d", "r5:5", 0, 0, 0, 0}, ++ {0x003f0010, 0xffff801f, "x86sbc.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0011, 0xffff801f, "x86sbc.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0012, 0xffff801f, "x86sbc.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0013, 0xffff801f, "x86sbc.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0008, 0xffff801f, "x86sub.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0009, 0xffff801f, "x86sub.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f000a, 0xffff801f, "x86sub.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f000b, 0xffff801f, "x86sub.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0002, 0xffff801f, "x86sub.wu", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0003, 0xffff801f, "x86sub.du", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00008004, 0xfffffc1f, "x86dec.b", "r5:5", 0, 0, 0, 0}, ++ {0x00008005, 0xfffffc1f, "x86dec.h", "r5:5", 0, 0, 0, 0}, ++ {0x00008006, 0xfffffc1f, "x86dec.w", "r5:5", 0, 0, 0, 0}, ++ {0x00008007, 0xfffffc1f, "x86dec.d", "r5:5", 0, 0, 0, 0}, ++ {0x003f8010, 0xffff801f, "x86and.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8011, 0xffff801f, "x86and.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8012, 0xffff801f, "x86and.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8013, 0xffff801f, "x86and.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8014, 0xffff801f, "x86or.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8015, 0xffff801f, "x86or.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8016, 0xffff801f, "x86or.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8017, 0xffff801f, "x86or.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8018, 0xffff801f, "x86xor.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8019, 0xffff801f, "x86xor.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f801a, 0xffff801f, "x86xor.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f801b, 0xffff801f, "x86xor.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003e8000, 0xffff801f, "x86mul.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003e8001, 0xffff801f, "x86mul.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003e8002, 0xffff801f, "x86mul.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003e8003, 0xffff801f, "x86mul.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003e8004, 0xffff801f, "x86mul.bu", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003e8005, 0xffff801f, "x86mul.hu", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003e8006, 0xffff801f, "x86mul.wu", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003e8007, 0xffff801f, "x86mul.du", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f800c, 0xffff801f, "x86rcl.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f800d, 0xffff801f, "x86rcl.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f800e, 0xffff801f, "x86rcl.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f800f, 0xffff801f, "x86rcl.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00542018, 0xffffe01f, "x86rcli.b", "r5:5,u10:3", 0, 0, 0, 0}, ++ {0x00544019, 0xffffc01f, "x86rcli.h", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x0054801a, 0xffff801f, "x86rcli.w", "r5:5,u10:5", 0, 0, 0, 0}, ++ {0x0055001b, 0xffff001f, "x86rcli.d", "r5:5,u10:6", 0, 0, 0, 0}, ++ {0x003f8008, 0xffff801f, "x86rcr.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8009, 0xffff801f, "x86rcr.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f800a, 0xffff801f, "x86rcr.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f800b, 0xffff801f, "x86rcr.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00542010, 0xffffe01f, "x86rcri.b", "r5:5,u10:3", 0, 0, 0, 0}, ++ {0x00544011, 0xffffc01f, "x86rcri.h", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x00548012, 0xffff801f, "x86rcri.w", "r5:5,u10:5", 0, 0, 0, 0}, ++ {0x00550013, 0xffff001f, "x86rcri.d", "r5:5,u10:6", 0, 0, 0, 0}, ++ {0x003f8004, 0xffff801f, "x86rotl.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8005, 0xffff801f, "x86rotl.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8006, 0xffff801f, "x86rotl.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8007, 0xffff801f, "x86rotl.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00542014, 0xffffe01f, "x86rotli.b", "r5:5,u10:3", 0, 0, 0, 0}, ++ {0x00544015, 0xffffc01f, "x86rotli.h", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x00548016, 0xffff801f, "x86rotli.w", "r5:5,u10:5", 0, 0, 0, 0}, ++ {0x00550017, 0xffff001f, "x86rotli.d", "r5:5,u10:6", 0, 0, 0, 0}, ++ {0x003f8000, 0xffff801f, "x86rotr.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8001, 0xffff801f, "x86rotr.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8002, 0xffff801f, "x86rotr.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f8003, 0xffff801f, "x86rotr.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x0054200c, 0xffffe01f, "x86rotri.b", "r5:5,u10:3", 0, 0, 0, 0}, ++ {0x0054400d, 0xffffc01f, "x86rotri.h", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x0054800e, 0xffff801f, "x86rotri.w", "r5:5,u10:5", 0, 0, 0, 0}, ++ {0x0055000f, 0xffff001f, "x86rotri.d", "r5:5,u10:6", 0, 0, 0, 0}, ++ {0x003f0014, 0xffff801f, "x86sll.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0015, 0xffff801f, "x86sll.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0016, 0xffff801f, "x86sll.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0017, 0xffff801f, "x86sll.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00542000, 0xffffe01f, "x86slli.b", "r5:5,u10:3", 0, 0, 0, 0}, ++ {0x00544001, 0xffffc01f, "x86slli.h", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x00548002, 0xffff801f, "x86slli.w", "r5:5,u10:5", 0, 0, 0, 0}, ++ {0x00550003, 0xffff001f, "x86slli.d", "r5:5,u10:6", 0, 0, 0, 0}, ++ {0x003f0018, 0xffff801f, "x86srl.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f0019, 0xffff801f, "x86srl.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f001a, 0xffff801f, "x86srl.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f001b, 0xffff801f, "x86srl.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00542004, 0xffffe01f, "x86srli.b", "r5:5,u10:3", 0, 0, 0, 0}, ++ {0x00544005, 0xffffc01f, "x86srli.h", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x00548006, 0xffff801f, "x86srli.w", "r5:5,u10:5", 0, 0, 0, 0}, ++ {0x00550007, 0xffff001f, "x86srli.d", "r5:5,u10:6", 0, 0, 0, 0}, ++ {0x003f001c, 0xffff801f, "x86sra.b", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f001d, 0xffff801f, "x86sra.h", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f001e, 0xffff801f, "x86sra.w", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x003f001f, 0xffff801f, "x86sra.d", "r5:5,r10:5", 0, 0, 0, 0}, ++ {0x00542008, 0xffffe01f, "x86srai.b", "r5:5,u10:3", 0, 0, 0, 0}, ++ {0x00544009, 0xffffc01f, "x86srai.h", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x0054800a, 0xffff801f, "x86srai.w", "r5:5,u10:5", 0, 0, 0, 0}, ++ {0x0055000b, 0xffff001f, "x86srai.d", "r5:5,u10:6", 0, 0, 0, 0}, ++ {0x00368000, 0xffffc3e0, "setx86j", "r0:5,u10:4", 0, 0, 0, 0}, ++ {0x00007800, 0xfffffc00, "setx86loope", "r0:5,r5:5", 0, 0, 0, 0}, ++ {0x00007c00, 0xfffffc00, "setx86loopne", "r0:5,r5:5", 0, 0, 0, 0}, ++ {0x005c0000, 0xfffc03e0, "x86mfflag", "r0:5,u10:8", 0, 0, 0, 0}, ++ {0x005c0020, 0xfffc03e0, "x86mtflag", "r0:5,u10:8", 0, 0, 0, 0}, ++ {0x00007400, 0xffffffe0, "x86mftop", "r0:5", 0, 0, 0, 0}, ++ {0x00007000, 0xffffff1f, "x86mttop", "u5:3", 0, 0, 0, 0}, ++ {0x00008009, 0xffffffff, "x86inctop", "", 0, 0, 0, 0}, ++ {0x00008029, 0xffffffff, "x86dectop", "", 0, 0, 0, 0}, ++ {0x00008008, 0xffffffff, "x86settm", "", 0, 0, 0, 0}, ++ {0x00008028, 0xffffffff, "x86clrtm", "", 0, 0, 0, 0}, ++ {0x00580000, 0xfffc0000, "x86settag", "r0:5,u5:5,u10:8", 0, 0, 0, 0}, ++ {0x00370010, 0xffff8010, "armadd.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x00378010, 0xffff8010, "armsub.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x00380010, 0xffff8010, "armadc.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x00388010, 0xffff8010, "armsbc.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x00390010, 0xffff8010, "armand.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x00398010, 0xffff8010, "armor.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x003a0010, 0xffff8010, "armxor.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x003fc01c, 0xffffc01f, "armnot.w", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x003a8010, 0xffff8010, "armsll.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x003b0010, 0xffff8010, "armsrl.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x003b8010, 0xffff8010, "armsra.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x003c0010, 0xffff8010, "armrotr.w", "r5:5,r10:5,u0:4", 0, 0, 0, 0}, ++ {0x003c8010, 0xffff8010, "armslli.w", "r5:5,u10:5,u0:4", 0, 0, 0, 0}, ++ {0x003d0010, 0xffff8010, "armsrli.w", "r5:5,u10:5,u0:4", 0, 0, 0, 0}, ++ {0x003d8010, 0xffff8010, "armsrai.w", "r5:5,u10:5,u0:4", 0, 0, 0, 0}, ++ {0x003e0010, 0xffff8010, "armrotri.w", "r5:5,u10:5,u0:4", 0, 0, 0, 0}, ++ {0x003fc01f, 0xffffc01f, "armrrx.w", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x00364000, 0xffffc000, "armmove", "r0:5,r5:5,u10:4", 0, 0, 0, 0}, ++ {0x003fc01d, 0xffffc01f, "armmov.w", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x003fc01e, 0xffffc01f, "armmov.d", "r5:5,u10:4", 0, 0, 0, 0}, ++ {0x005c0040, 0xfffc03e0, "armmfflag", "r0:5,u10:8", 0, 0, 0, 0}, ++ {0x005c0060, 0xfffc03e0, "armmtflag", "r0:5,u10:8", 0, 0, 0, 0}, ++ {0x0036c000, 0xffffc3e0, "setarmj", "r0:5,u10:4", 0, 0, 0, 0}, ++ { 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list. */ ++}; + + struct loongarch_ase loongarch_ASEs[] = { + {&LARCH_opts.ase_test, loongarch_test_opcodes, 0, 0, {0}, 0, 0}, +@@ -2270,6 +2462,8 @@ struct loongarch_ase loongarch_ASEs[] = { + {&LARCH_opts.ase_float, loongarch_float_opcodes, 0, 0, {0}, 0, 0}, + {&LARCH_opts.ase_128vec, loongarch_128vec_opcodes, 0, 0, {0}, 0, 0}, + {&LARCH_opts.ase_256vec, loongarch_256vec_opcodes, 0, 0, {0}, 0, 0}, ++{&LARCH_opts.ase_lvz, loongarch_lvz_opcodes, 0, 0, {0}, 0, 0}, ++{&LARCH_opts.ase_lbt, loongarch_lbt_opcodes, 0, 0, {0}, 0, 0}, + + {0}, + }; +-- +2.43.5 + diff --git a/FCSR-fcsrX.patch b/FCSR-fcsrX.patch new file mode 100644 index 0000000000000000000000000000000000000000..80e44ac642b4907e0b9bf4871c9dbff9fe0488ac --- /dev/null +++ b/FCSR-fcsrX.patch @@ -0,0 +1,188 @@ +From 40faf01587f77638b0fcbf70adfa1ee24de5fdea Mon Sep 17 00:00:00 2001 +From: cailulu +Date: Mon, 1 Jul 2024 11:32:07 +0800 +Subject: [PATCH 5/5] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=B0=86FCSR=E5=AF=84?= + =?UTF-8?q?=E5=AD=98=E5=99=A8=E5=90=8D=E5=BC=95=E7=94=A8=E4=B8=BA$fcsrX?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +以前,FCSR寄存器名称被引用为$rX,这看起来很奇怪。 +添加修改支持使用$fcsrX作为寄存器名称,这也能确保与 LLVM IAS 兼容。 + +Change-Id: Ia4448e39de582bb17332fefd4378e6ac3a21c3bd +--- + gas/config/tc-loongarch.c | 23 ++++++++++++++++++++++- + gas/testsuite/gas/loongarch/fcsr.d | 11 +++++++++++ + gas/testsuite/gas/loongarch/fcsr.s | 2 ++ + include/opcode/loongarch.h | 2 ++ + opcodes/loongarch-dis.c | 11 ++++++++++- + opcodes/loongarch-opc.c | 14 ++++++++++++-- + 6 files changed, 59 insertions(+), 4 deletions(-) + create mode 100644 gas/testsuite/gas/loongarch/fcsr.d + create mode 100644 gas/testsuite/gas/loongarch/fcsr.s + +diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c +index 331cfe50..7a93f1a2 100644 +--- a/gas/config/tc-loongarch.c ++++ b/gas/config/tc-loongarch.c +@@ -150,6 +150,8 @@ md_parse_option (int c, const char *arg) + + static struct hash_control *r_htab = NULL; + static struct hash_control *f_htab = NULL; ++static struct hash_control *fc_htab = NULL; ++static struct hash_control *fcn_htab = NULL; + static struct hash_control *c_htab = NULL; + static struct hash_control *cr_htab = NULL; + static struct hash_control *v_htab = NULL; +@@ -170,6 +172,10 @@ loongarch_after_parse_args () + r_htab = hash_new (), hash_insert (r_htab, "", 0); + if (!f_htab) + f_htab = hash_new (), hash_insert (f_htab, "", 0); ++ if (!fc_htab) ++ fc_htab = hash_new (), hash_insert (fc_htab, "", 0); ++ if (!fcn_htab) ++ fcn_htab = hash_new (), hash_insert (fcn_htab, "", 0); + if (!c_htab) + c_htab = hash_new (), hash_insert (c_htab, "", 0); + if (!cr_htab) +@@ -183,6 +189,10 @@ loongarch_after_parse_args () + hash_insert (r_htab, loongarch_r_normal_name[i], (void *) (i + 1)); + for (i = 0; i < ARRAY_SIZE (loongarch_f_normal_name); i++) + hash_insert (f_htab, loongarch_f_normal_name[i], (void *) (i + 1)); ++ for (i = 0; i < ARRAY_SIZE (loongarch_fc_normal_name); i++) ++ hash_insert (fc_htab, loongarch_fc_normal_name[i], (void *) (i + 1)); ++ for (i = 0; i < ARRAY_SIZE (loongarch_fc_numeric_name); i++) ++ hash_insert (fcn_htab, loongarch_fc_numeric_name[i], (void *) (i + 1)); + for (i = 0; i < ARRAY_SIZE (loongarch_c_normal_name); i++) + hash_insert (c_htab, loongarch_c_normal_name[i], (void *) (i + 1)); + for (i = 0; i < ARRAY_SIZE (loongarch_cr_normal_name); i++) +@@ -587,7 +597,18 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, + ret = imm - 1; + break; + case 'f': +- imm = (offsetT) hash_find (f_htab, arg); ++ switch (esc_ch2) ++ { ++ case 'c': ++ imm = (offsetT) hash_find (fc_htab, arg); ++ if (0 >= imm) ++ { ++ imm = (offsetT) hash_find (fcn_htab, arg); ++ } ++ break; ++ default: ++ imm = (offsetT) hash_find (f_htab, arg); ++ } + ip->match_now = 0 < imm; + ret = imm - 1; + break; +diff --git a/gas/testsuite/gas/loongarch/fcsr.d b/gas/testsuite/gas/loongarch/fcsr.d +new file mode 100644 +index 00000000..342b7cbc +--- /dev/null ++++ b/gas/testsuite/gas/loongarch/fcsr.d +@@ -0,0 +1,11 @@ ++#as: ++#objdump: -dr ++ ++.*: file format .* ++ ++ ++Disassembly of section .text: ++ ++0* <.text>: ++ 0: 0114c0a0 movgr2fcsr \$fcsr0,\$r5 ++ 4: 0114c804 movfcsr2gr \$r4,\$fcsr0 +diff --git a/gas/testsuite/gas/loongarch/fcsr.s b/gas/testsuite/gas/loongarch/fcsr.s +new file mode 100644 +index 00000000..5484fc54 +--- /dev/null ++++ b/gas/testsuite/gas/loongarch/fcsr.s +@@ -0,0 +1,2 @@ ++movgr2fcsr $fcsr0,$r5 ++movfcsr2gr $r4,$fcsr0 +diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h +index 94973cbd..de3642a8 100644 +--- a/include/opcode/loongarch.h ++++ b/include/opcode/loongarch.h +@@ -179,6 +179,8 @@ extern const char * const loongarch_r_lp64_name1[32]; + extern const char * const loongarch_f_normal_name[32]; + extern const char * const loongarch_f_lp64_name[32]; + extern const char * const loongarch_f_lp64_name1[32]; ++extern const char * const loongarch_fc_normal_name[4]; ++extern const char * const loongarch_fc_numeric_name[4]; + extern const char * const loongarch_c_normal_name[8]; + extern const char * const loongarch_cr_normal_name[4]; + extern const char * const loongarch_v_normal_name[32]; +diff --git a/opcodes/loongarch-dis.c b/opcodes/loongarch-dis.c +index b34847be..9a45660b 100644 +--- a/opcodes/loongarch-dis.c ++++ b/opcodes/loongarch-dis.c +@@ -43,6 +43,7 @@ get_loongarch_opcode_by_binfmt (insn_t insn) + + static const char * const *loongarch_r_disname = NULL; + static const char * const *loongarch_f_disname = NULL; ++static const char * const *loongarch_fc_disname = NULL; + static const char * const *loongarch_c_disname = NULL; + static const char * const *loongarch_cr_disname = NULL; + static const char * const *loongarch_v_disname = NULL; +@@ -61,6 +62,7 @@ set_default_loongarch_dis_options (void) + + loongarch_r_disname = loongarch_r_normal_name; + loongarch_f_disname = loongarch_f_normal_name; ++ loongarch_fc_disname = loongarch_fc_normal_name; + loongarch_c_disname = loongarch_c_normal_name; + loongarch_cr_disname = loongarch_cr_normal_name; + loongarch_v_disname = loongarch_v_normal_name; +@@ -120,7 +122,14 @@ dis_one_arg (char esc1, char esc2, const char *bit_field, + info->fprintf_func (info->stream, "%s", loongarch_r_disname[u_imm]); + break; + case 'f': +- info->fprintf_func (info->stream, "%s", loongarch_f_disname[u_imm]); ++ switch (esc2) ++ { ++ case 'c': ++ info->fprintf_func (info->stream, "%s", loongarch_fc_disname[u_imm]); ++ break; ++ default: ++ info->fprintf_func (info->stream, "%s", loongarch_f_disname[u_imm]); ++ } + break; + case 'c': + switch (esc2) +diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c +index 1e251e3d..687e5a6f 100644 +--- a/opcodes/loongarch-opc.c ++++ b/opcodes/loongarch-opc.c +@@ -75,6 +75,16 @@ const char * const loongarch_f_lp64_name1[32] = + "", "", "", "", "", "", "", "", + }; + ++const char *const loongarch_fc_normal_name[4] = ++{ ++ "$fcsr0", "$fcsr1", "$fcsr2", "$fcsr3", ++}; ++ ++const char *const loongarch_fc_numeric_name[4] = ++{ ++ "$r0", "$r1", "$r2", "$r3", ++}; ++ + const char * const loongarch_c_normal_name[8] = + { + "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7", +@@ -413,8 +423,8 @@ static struct loongarch_opcode loongarch_float_opcodes[] = { + {0x0114b400, 0xfffffc00, "movfr2gr.s", "r0:5,f5:5", 0, 0, 0, 0}, + {0x0114b800, 0xfffffc00, "movfr2gr.d", "r0:5,f5:5", 0, 0, 0, 0}, + {0x0114bc00, 0xfffffc00, "movfrh2gr.s", "r0:5,f5:5", 0, 0, 0, 0}, +-{0x0114c000, 0xfffffc00, "movgr2fcsr", "r0:5,r5:5", 0, 0, 0, 0}, +-{0x0114c800, 0xfffffc00, "movfcsr2gr", "r0:5,r5:5", 0, 0, 0, 0}, ++{0x0114c000, 0xfffffc1c, "movgr2fcsr", "fc0:2,r5:5", 0, 0, 0, 0}, ++{0x0114c800, 0xffffff80, "movfcsr2gr", "r0:5,fc5:2", 0, 0, 0, 0}, + {0x0114d000, 0xfffffc18, "movfr2cf", "c0:3,f5:5", 0, 0, 0, 0}, + {0x0114d400, 0xffffff00, "movcf2fr", "f0:5,c5:3", 0, 0, 0, 0}, + {0x0114d800, 0xfffffc18, "movgr2cf", "c0:3,r5:5", 0, 0, 0, 0}, +-- +2.43.5 + diff --git a/Fix-behavior-of-as-and-ld-when-relocation-overflows.patch b/Fix-behavior-of-as-and-ld-when-relocation-overflows.patch new file mode 100644 index 0000000000000000000000000000000000000000..63a1fd92a3fbf1d8313a4fd47a0f967efe9767de --- /dev/null +++ b/Fix-behavior-of-as-and-ld-when-relocation-overflows.patch @@ -0,0 +1,272 @@ +From 380c216f2d9fdc0c8f58cc26f93191a1347bf3aa Mon Sep 17 00:00:00 2001 +From: cailulu +Date: Tue, 30 Apr 2024 11:02:32 +0800 +Subject: [PATCH 3/5] Fix behavior of as and ld when relocation overflows +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1. Modify as_warn_where to as_bad_where to terminate the assembly + process when relocation overflows. + +2. Modify the error message of ld when relocation overflows. + before: + ./ld-new: 最后的链结失败: symbol needs debug section which does not exist + after: + ./ld-new: 最后的链结失败: bad value + +Change-Id: If6b0f0cf8f4d3887f2c723751c9d051d6a54712e +--- + bfd/elflink.c | 3 +- + bfd/elfnn-loongarch.c | 60 +++++++++++++++++++++++++++++++-------- + gas/config/tc-loongarch.c | 22 +++++++------- + 3 files changed, 61 insertions(+), 24 deletions(-) + +diff --git a/bfd/elflink.c b/bfd/elflink.c +index 42f65a15..deb37922 100644 +--- a/bfd/elflink.c ++++ b/bfd/elflink.c +@@ -11319,7 +11319,8 @@ elf_fixup_link_order (bfd *abfd, asection *o) + { + s = p->u.indirect.section; + sub = s->owner; +- if (bfd_get_flavour (sub) == bfd_target_elf_flavour ++ if ((s->flags & SEC_LINKER_CREATED) == 0 ++ && bfd_get_flavour (sub) == bfd_target_elf_flavour + && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass + && (elfsec = _bfd_elf_section_from_bfd_section (sub, s)) + && elfsec < elf_numsections (sub) +diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c +index 7dbdd7cf..30217678 100644 +--- a/bfd/elfnn-loongarch.c ++++ b/bfd/elfnn-loongarch.c +@@ -2054,7 +2054,10 @@ perform_relocation (const Elf_Internal_Rela *rel, + break; + if ((opr1 & ~(uint64_t)0xf) != 0x0 + && (opr1 & ~(uint64_t)0xf) != ~(uint64_t)0xf) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + if (r != bfd_reloc_ok) + break; + insn1 = bfd_get (32, input_bfd, contents + rel->r_offset); +@@ -2067,7 +2070,10 @@ perform_relocation (const Elf_Internal_Rela *rel, + if (r != bfd_reloc_ok) + break; + if (opr1 & ~(uint64_t)0xfff) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + if (r != bfd_reloc_ok) + break; + insn1 = bfd_get (32, input_bfd, contents + rel->r_offset); +@@ -2081,7 +2087,10 @@ perform_relocation (const Elf_Internal_Rela *rel, + break; + if ((opr1 & ~(uint64_t)0x7ff) != 0x0 + && (opr1 & ~(uint64_t)0x7ff) != ~(uint64_t)0x7ff) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + if (r != bfd_reloc_ok) + break; + insn1 = bfd_get (32, input_bfd, contents + rel->r_offset); +@@ -2095,7 +2104,10 @@ perform_relocation (const Elf_Internal_Rela *rel, + break; + if ((opr1 & ~(uint64_t)0x7fff) != 0x0 + && (opr1 & ~(uint64_t)0x7fff) != ~(uint64_t)0x7fff) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + if (r != bfd_reloc_ok) + break; + insn1 = bfd_get (32, input_bfd, contents + rel->r_offset); +@@ -2108,11 +2120,17 @@ perform_relocation (const Elf_Internal_Rela *rel, + if (r != bfd_reloc_ok) + break; + if ((opr1 & 0x3) != 0) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + opr1 >>= 2; + if ((opr1 & ~(uint64_t)0x7fff) != 0x0 + && (opr1 & ~(uint64_t)0x7fff) != ~(uint64_t)0x7fff) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + if (r != bfd_reloc_ok) + break; + insn1 = bfd_get (32, input_bfd, contents + rel->r_offset); +@@ -2125,11 +2143,17 @@ perform_relocation (const Elf_Internal_Rela *rel, + if (r != bfd_reloc_ok) + break; + if ((opr1 & 0x3) != 0) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + opr1 >>= 2; + if ((opr1 & ~(uint64_t)0xfffff) != 0x0 + && (opr1 & ~(uint64_t)0xfffff) != ~(uint64_t)0xfffff) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + if (r != bfd_reloc_ok) + break; + insn1 = bfd_get (32, input_bfd, contents + rel->r_offset); +@@ -2144,7 +2168,10 @@ perform_relocation (const Elf_Internal_Rela *rel, + break; + if ((opr1 & ~(uint64_t)0x7ffff) != 0x0 + && (opr1 & ~(uint64_t)0x7ffff) != ~(uint64_t)0x7ffff) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + if (r != bfd_reloc_ok) + break; + insn1 = bfd_get (32, input_bfd, contents + rel->r_offset); +@@ -2157,11 +2184,17 @@ perform_relocation (const Elf_Internal_Rela *rel, + if (r != bfd_reloc_ok) + break; + if ((opr1 & 0x3) != 0) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + opr1 >>= 2; + if ((opr1 & ~(uint64_t)0x1ffffff) != 0x0 + && (opr1 & ~(uint64_t)0x1ffffff) != ~(uint64_t)0x1ffffff) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + if (r != bfd_reloc_ok) + break; + insn1 = bfd_get (32, input_bfd, contents + rel->r_offset); +@@ -2175,7 +2208,10 @@ perform_relocation (const Elf_Internal_Rela *rel, + if (r != bfd_reloc_ok) + break; + if (opr1 & ~(uint64_t)0xffffffff) +- r = bfd_reloc_overflow; ++ { ++ r = bfd_reloc_overflow; ++ bfd_set_error (bfd_error_bad_value); ++ } + if (r != bfd_reloc_ok) + break; + bfd_put (32, input_bfd, opr1, contents + rel->r_offset); +diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c +index 9b9cb827..4135b0b1 100644 +--- a/gas/config/tc-loongarch.c ++++ b/gas/config/tc-loongarch.c +@@ -1033,7 +1033,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) + break; + if ((stack_top & ~(uint64_t)0xf) != 0x0 + && (stack_top & ~(uint64_t)0xf) != ~(uint64_t)0xf) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + insn = bfd_getl32 (buf); + insn = (insn & (~(uint32_t)0x7c00)) | ((stack_top & 0x1f) << 10); + bfd_putl32 (insn, buf); +@@ -1043,7 +1043,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) + if (!last_reloc_is_sop_push_pcrel) + break; + if (stack_top & ~(uint64_t)0xfff) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + insn = bfd_getl32 (buf); + insn = (insn & (~(uint32_t)0x3ffc00)) | ((stack_top & 0xfff) << 10); + bfd_putl32 (insn, buf); +@@ -1054,7 +1054,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) + break; + if ((stack_top & ~(uint64_t)0x7ff) != 0x0 + && (stack_top & ~(uint64_t)0x7ff) != ~(uint64_t)0x7ff) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + insn = bfd_getl32 (buf); + insn = (insn & (~(uint32_t)0x3ffc00)) | ((stack_top & 0xfff) << 10); + bfd_putl32 (insn, buf); +@@ -1065,7 +1065,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) + break; + if ((stack_top & ~(uint64_t)0x7fff) != 0x0 + && (stack_top & ~(uint64_t)0x7fff) != ~(uint64_t)0x7fff) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + insn = bfd_getl32 (buf); + insn = (insn & 0xfc0003ff) | ((stack_top & 0xffff) << 10); + bfd_putl32 (insn, buf); +@@ -1075,11 +1075,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) + if (!last_reloc_is_sop_push_pcrel) + break; + if ((stack_top & 0x3) != 0) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + stack_top >>= 2; + if ((stack_top & ~(uint64_t)0x7fff) != 0x0 + && (stack_top & ~(uint64_t)0x7fff) != ~(uint64_t)0x7fff) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + insn = bfd_getl32 (buf); + insn = (insn & 0xfc0003ff) | ((stack_top & 0xffff) << 10); + bfd_putl32 (insn, buf); +@@ -1093,7 +1093,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) + stack_top >>= 2; + if ((stack_top & ~(uint64_t)0xfffff) != 0x0 + && (stack_top & ~(uint64_t)0xfffff) != ~(uint64_t)0xfffff) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + insn = bfd_getl32 (buf); + insn = (insn & 0xfc0003e0) + | ((stack_top & 0xffff) << 10) | ((stack_top & 0x1f0000) >> 16); +@@ -1105,7 +1105,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) + break; + if ((stack_top & ~(uint64_t)0x7ffff) != 0x0 + && (stack_top & ~(uint64_t)0x7ffff) != ~(uint64_t)0x7ffff) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + insn = bfd_getl32 (buf); + insn = (insn & (~(uint32_t)0x1ffffe0)) | ((stack_top & 0xfffff) << 5); + bfd_putl32 (insn, buf); +@@ -1115,11 +1115,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) + if (!last_reloc_is_sop_push_pcrel) + break; + if ((stack_top & 0x3) != 0) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + stack_top >>= 2; + if ((stack_top & ~(uint64_t)0x1ffffff) != 0x0 + && (stack_top & ~(uint64_t)0x1ffffff) != ~(uint64_t)0x1ffffff) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + insn = bfd_getl32 (buf); + insn = (insn & 0xfc000000) + | ((stack_top & 0xffff) << 10) | ((stack_top & 0x3ff0000) >> 16); +@@ -1130,7 +1130,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) + if (!last_reloc_is_sop_push_pcrel) + break; + if (stack_top & ~(uint64_t)0xffffffff) +- as_warn_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); ++ as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); + bfd_putl32 (stack_top, buf); + break; + +-- +2.43.5 + diff --git a/LoongArch-Add-bad-static-relocation-check.patch b/LoongArch-Add-bad-static-relocation-check.patch new file mode 100644 index 0000000000000000000000000000000000000000..1e1b76001995b60981f365f073b57afcbf1b8fb3 --- /dev/null +++ b/LoongArch-Add-bad-static-relocation-check.patch @@ -0,0 +1,52 @@ +From fc9b90e5d3f95e8c9a96c3c02c14b687f41f95ee Mon Sep 17 00:00:00 2001 +From: cailulu +Date: Sat, 23 Mar 2024 17:28:47 +0800 +Subject: [PATCH 2/5] LoongArch: Add bad static relocation check + +TLS le symbols cannot be used with -shared. + +Change-Id: I72c8ab1d4428f505e42b6a004d48875a2b356a61 +--- + bfd/elfnn-loongarch.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c +index 2fb37578..7dbdd7cf 100644 +--- a/bfd/elfnn-loongarch.c ++++ b/bfd/elfnn-loongarch.c +@@ -603,6 +603,23 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd, + return TRUE; + } + ++ ++static bfd_boolean ++bad_static_reloc (bfd *abfd, unsigned r_type, struct elf_link_hash_entry *h) ++{ ++ /* We propably can improve the information to tell users that they should ++ be recompile the code with -fPIC or -fPIE, just like what x86 does. */ ++ reloc_howto_type * r = loongarch_elf_rtype_to_howto (r_type); ++ (*_bfd_error_handler) ++ (_("%pB: relocation %s against `%s` can not be used when making a shared " ++ "object; recompile with -fPIC"), ++ abfd, r ? r->name : _(""), ++ h != NULL ? h->root.root.string : "a local symbol"); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++} ++ ++ + /* Look through the relocs for a section during the first phase, and + allocate space in the global offset table or procedure linkage + table. */ +@@ -756,7 +773,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, + + case R_LARCH_SOP_PUSH_TLS_TPREL: + if (!bfd_link_executable (info)) +- return FALSE; ++ return bad_static_reloc (abfd, r_type, h); + + info->flags |= DF_STATIC_TLS; + +-- +2.43.5 + diff --git a/Move-the-dynamic-relocation-of-local-ifunc-from-the-.patch b/Move-the-dynamic-relocation-of-local-ifunc-from-the-.patch new file mode 100644 index 0000000000000000000000000000000000000000..7aa484b66e32a0b6f7d94129836e682bfc73d032 --- /dev/null +++ b/Move-the-dynamic-relocation-of-local-ifunc-from-the-.patch @@ -0,0 +1,448 @@ +From b4a9ea4dd660ad182396638dc87d8e491f0b0938 Mon Sep 17 00:00:00 2001 +From: mengqinggang +Date: Mon, 26 Jun 2023 14:32:23 +0800 +Subject: [PATCH 1/5] Move the dynamic relocation of local ifunc from the + rela.plt section to the rela.dyn section + +Change-Id: I6ce5af8bfe5b6022ac0b4e468a03afc64c73b6cf +--- + bfd/elfnn-loongarch.c | 344 ++++++++++++++++++++++++++++++++++++++++-- + bfd/elfxx-loongarch.h | 8 + + 2 files changed, 336 insertions(+), 16 deletions(-) + +diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c +index ac4bcc20..2fb37578 100644 +--- a/bfd/elfnn-loongarch.c ++++ b/bfd/elfnn-loongarch.c +@@ -674,8 +674,14 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, + if (h == NULL) + return FALSE; + ++ /* Fake STT_GNU_IFUNC global symbol. */ ++ h->root.root.string = bfd_elf_sym_name (abfd, symtab_hdr, ++ isym, NULL); + h->type = STT_GNU_IFUNC; ++ h->def_regular = 1; + h->ref_regular = 1; ++ h->forced_local = 1; ++ h->root.type = bfd_link_hash_defined; + } + else + h = NULL; +@@ -1283,6 +1289,272 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) + return TRUE; + } + ++/* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs. ++ For local def and ref ifunc, ++ dynamic relocations are stored in ++ 1. rela.srelgot section in dynamic object (dll or exec). ++ 2. rela.irelplt section in static executable. ++ Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used ++ instead of rela.srelplt. Glibc ELF loader will not support ++ R_LARCH_IRELATIVE relocation in rela.plt. */ ++static bfd_boolean ++local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h, ++ struct elf_dyn_relocs **head, ++ bfd_boolean *readonly_dynrelocs_against_ifunc_p, ++ unsigned int plt_entry_size, ++ unsigned int plt_header_size, ++ unsigned int got_entry_size, ++ bfd_boolean avoid_plt) ++{ ++ asection *plt, *gotplt, *relplt; ++ struct elf_dyn_relocs *p; ++ unsigned int sizeof_reloc; ++ const struct elf_backend_data *bed; ++ struct elf_link_hash_table *htab; ++ bfd_boolean readonly_dynrelocs_against_ifunc; ++ /* If AVOID_PLT is TRUE, don't use PLT if possible. */ ++ bfd_boolean use_plt = !avoid_plt || h->plt.refcount > 0; ++ bfd_boolean need_dynreloc = !use_plt || bfd_link_pic (info); ++ ++ /* When a PIC object references a STT_GNU_IFUNC symbol defined ++ in executable or it isn't referenced via PLT, the address of ++ the resolved function may be used. But in non-PIC executable, ++ the address of its .plt slot may be used. Pointer equality may ++ not work correctly. PIE or non-PLT reference should be used if ++ pointer equality is required here. ++ ++ If STT_GNU_IFUNC symbol is defined in position-dependent executable, ++ backend should change it to the normal function and set its address ++ to its PLT entry which should be resolved by R_*_IRELATIVE at ++ run-time. All external references should be resolved to its PLT in ++ executable. */ ++ if (!need_dynreloc ++ && !(bfd_link_pde (info) && h->def_regular) ++ && (h->dynindx != -1 ++ || info->export_dynamic) ++ && h->pointer_equality_needed) ++ { ++ info->callbacks->einfo ++ /* xgettext:c-format */ ++ (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer " ++ "equality in `%pB' can not be used when making an " ++ "executable; recompile with -fPIE and relink with -pie\n"), ++ h->root.root.string, ++ h->root.u.def.section->owner); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ htab = elf_hash_table (info); ++ ++ /* When the symbol is marked with regular reference, if PLT isn't used ++ or we are building a PIC object, we must keep dynamic relocation ++ if there is non-GOT reference and use PLT if there is PC-relative ++ reference. */ ++ if (need_dynreloc && h->ref_regular) ++ { ++ bfd_boolean keep = FALSE; ++ for (p = *head; p != NULL; p = p->next) ++ if (p->count) ++ { ++ h->non_got_ref = 1; ++ /* Need dynamic relocations for non-GOT reference. */ ++ keep = TRUE; ++ if (p->pc_count) ++ { ++ /* Must use PLT for PC-relative reference. */ ++ use_plt = TRUE; ++ need_dynreloc = bfd_link_pic (info); ++ break; ++ } ++ } ++ if (keep) ++ goto keep; ++ } ++ ++ /* Support garbage collection against STT_GNU_IFUNC symbols. */ ++ if (h->plt.refcount <= 0 && h->got.refcount <= 0) ++ { ++ h->got = htab->init_got_offset; ++ h->plt = htab->init_plt_offset; ++ *head = NULL; ++ return TRUE; ++ } ++ ++ /* Return and discard space for dynamic relocations against it if ++ it is never referenced. */ ++ if (!h->ref_regular) ++ { ++ if (h->plt.refcount > 0 ++ || h->got.refcount > 0) ++ abort (); ++ h->got = htab->init_got_offset; ++ h->plt = htab->init_plt_offset; ++ *head = NULL; ++ return TRUE; ++ } ++ ++keep: ++ bed = get_elf_backend_data (info->output_bfd); ++ if (bed->rela_plts_and_copies_p) ++ sizeof_reloc = bed->s->sizeof_rela; ++ else ++ sizeof_reloc = bed->s->sizeof_rel; ++ ++ /* When building a static executable, use .iplt, .igot.plt and ++ .rel[a].iplt sections for STT_GNU_IFUNC symbols. */ ++ if (htab->splt != NULL) ++ { ++ plt = htab->splt; ++ gotplt = htab->sgotplt; ++ //relplt = htab->srelplt; ++ /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */ ++ relplt = htab->srelgot; ++ ++ /* If this is the first .plt entry and PLT is used, make room for ++ the special first entry. */ ++ if (plt->size == 0 && use_plt) ++ plt->size += plt_header_size; ++ } ++ else ++ { ++ plt = htab->iplt; ++ gotplt = htab->igotplt; ++ relplt = htab->irelplt; ++ } ++ ++ if (use_plt) ++ { ++ /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need ++ the original value for R_*_IRELATIVE. */ ++ h->plt.offset = plt->size; ++ ++ /* Make room for this entry in the .plt/.iplt section. */ ++ plt->size += plt_entry_size; ++ ++ /* We also need to make an entry in the .got.plt/.got.iplt section, ++ which will be placed in the .got section by the linker script. */ ++ gotplt->size += got_entry_size; ++ } ++ ++ /* We also need to make an entry in the .rel[a].plt/.rel[a].iplt ++ section for GOTPLT relocation if PLT is used. */ ++ if (use_plt) ++ { ++ relplt->size += sizeof_reloc; ++ relplt->reloc_count++; ++ } ++ ++ /* We need dynamic relocation for STT_GNU_IFUNC symbol only when ++ there is a non-GOT reference in a PIC object or PLT isn't used. */ ++ if (!need_dynreloc || !h->non_got_ref) ++ *head = NULL; ++ ++ readonly_dynrelocs_against_ifunc = FALSE; ++ ++ /* Finally, allocate space. */ ++ p = *head; ++ if (p != NULL) ++ { ++ bfd_size_type count = 0; ++ do ++ { ++ if (!readonly_dynrelocs_against_ifunc) ++ { ++ asection *s = p->sec->output_section; ++ if (s != NULL && (s->flags & SEC_READONLY) != 0) ++ readonly_dynrelocs_against_ifunc = TRUE; ++ } ++ count += p->count; ++ p = p->next; ++ } ++ while (p != NULL); ++ ++ /* Dynamic relocations are stored in ++ 1. .rel[a].ifunc section in PIC object. ++ 2. .rel[a].got section in dynamic executable. ++ 3. .rel[a].iplt section in static executable. */ ++ if (htab->splt != NULL) ++ htab->srelgot->size += count * sizeof_reloc; ++ else ++ { ++ relplt->size += count * sizeof_reloc; ++ relplt->reloc_count += count; ++ } ++ } ++ ++ if (readonly_dynrelocs_against_ifunc_p) ++ *readonly_dynrelocs_against_ifunc_p = readonly_dynrelocs_against_ifunc; ++ ++ /* For STT_GNU_IFUNC symbol, .got.plt has the real function address ++ and .got has the PLT entry adddress. We will load the GOT entry ++ with the PLT entry in finish_dynamic_symbol if it is used. For ++ branch, it uses .got.plt. For symbol value, if PLT is used, ++ 1. Use .got.plt in a PIC object if it is forced local or not ++ dynamic. ++ 2. Use .got.plt in a non-PIC object if pointer equality isn't ++ needed. ++ 3. Use .got.plt in PIE. ++ 4. Use .got.plt if .got isn't used. ++ 5. Otherwise use .got so that it can be shared among different ++ objects at run-time. ++ If PLT isn't used, always use .got for symbol value. ++ We only need to relocate .got entry in PIC object or in dynamic ++ executable without PLT. */ ++ if (use_plt ++ && (h->got.refcount <= 0 ++ || (bfd_link_pic (info) ++ && (h->dynindx == -1 ++ || h->forced_local)) ++ || (!bfd_link_pic (info) ++ && !h->pointer_equality_needed) ++ || bfd_link_pie (info) ++ || htab->sgot == NULL)) ++ { ++ /* Use .got.plt. */ ++ h->got.offset = (bfd_vma) -1; ++ } ++ else ++ { ++ if (!use_plt) ++ { ++ /* PLT isn't used. */ ++ h->plt.offset = (bfd_vma) -1; ++ } ++ if (h->got.refcount <= 0) ++ { ++ /* GOT isn't need when there are only relocations for static ++ pointers. */ ++ h->got.offset = (bfd_vma) -1; ++ } ++ else ++ { ++ h->got.offset = htab->sgot->size; ++ htab->sgot->size += got_entry_size; ++ /* Need to relocate the GOT entry in a PIC object or PLT isn't ++ used. Otherwise, the GOT entry will be filled with the PLT ++ entry and dynamic GOT relocation isn't needed. */ ++ if (need_dynreloc) ++ { ++ /* For non-static executable, dynamic GOT relocation is in ++ .rel[a].got section, but for static executable, it is ++ in .rel[a].iplt section. */ ++ if (htab->splt != NULL) ++ htab->srelgot->size += sizeof_reloc; ++ else ++ { ++ relplt->size += sizeof_reloc; ++ relplt->reloc_count++; ++ } ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++ + /* Allocate space in .plt, .got and associated reloc sections for + ifunc dynamic relocs. */ + +@@ -1311,13 +1583,22 @@ elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf) + here if it is defined and referenced in a non-shared object. */ + if (h->type == STT_GNU_IFUNC && h->def_regular) + { +- return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, ++ if (SYMBOL_REFERENCES_LOCAL (info, h)) ++ return local_allocate_ifunc_dyn_relocs (info, h, ++ &loongarch_elf_hash_entry(h)->dyn_relocs, ++ NULL, ++ PLT_ENTRY_SIZE, ++ PLT_HEADER_SIZE, ++ GOT_ENTRY_SIZE, ++ FALSE); ++ else ++ return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, + &loongarch_elf_hash_entry(h)->dyn_relocs, + NULL, +- PLT_ENTRY_SIZE, +- PLT_HEADER_SIZE, +- GOT_ENTRY_SIZE, +- FALSE); ++ PLT_ENTRY_SIZE, ++ PLT_HEADER_SIZE, ++ GOT_ENTRY_SIZE, ++ FALSE); + } + + return TRUE; +@@ -2986,7 +3267,10 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, + + plt = htab->elf.splt; + gotplt = htab->elf.sgotplt; +- relplt = htab->elf.srelplt; ++ if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h)) ++ relplt = htab->elf.srelgot; ++ else ++ relplt = htab->elf.srelplt; + plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; + got_address = sec_addr (gotplt) + GOTPLT_HEADER_SIZE + + plt_idx * GOT_ENTRY_SIZE; +@@ -3018,23 +3302,28 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, + bfd_put_NN (output_bfd, sec_addr (plt), loc); + + rela.r_offset = got_address; +- if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h)) ++ ++ /* TRUE if this is a PLT reference to a local IFUNC. */ ++ if (PLT_LOCAL_IFUNC_P (info, h) ++ && (relplt == htab->elf.srelgot ++ || relplt == htab->elf.irelplt)) + { + rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE); +- rela.r_addend = h->root.u.def.value +- + h->root.u.def.section->output_section->vma +- + h->root.u.def.section->output_offset; ++ rela.r_addend = (h->root.u.def.value ++ + h->root.u.def.section->output_section->vma ++ + h->root.u.def.section->output_offset); ++ ++ loongarch_elf_append_rela (output_bfd, relplt, &rela); + } + else + { +- /* Fill in the entry in the .rela.plt section. */ ++ /* Fill in the entry in the rela.plt section. */ + rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT); + rela.r_addend = 0; ++ loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela); ++ bed->s->swap_reloca_out (output_bfd, &rela, loc); + } + +- loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela); +- bed->s->swap_reloca_out (output_bfd, &rela, loc); +- + if (!h->def_regular) + { + /* Mark the symbol as undefined, rather than as defined in +@@ -3222,6 +3511,30 @@ elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf) + return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL); + } + ++static bfd_boolean ++elf_loongarch_output_arch_local_syms ++ (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info, ++ void *flaginfo ATTRIBUTE_UNUSED, ++ int (*func) (void *, const char *, ++ Elf_Internal_Sym *, ++ asection *, ++ struct elf_link_hash_entry *) ATTRIBUTE_UNUSED) ++{ ++ struct loongarch_elf_link_hash_table *htab ++ = loongarch_elf_hash_table (info); ++ if (htab == NULL) ++ return FALSE; ++ ++ /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ ++ htab_traverse (htab->loc_hash_table, ++ elfNN_loongarch_finish_local_dynamic_symbol, ++ info); ++ ++ return TRUE; ++} ++ ++ + static bfd_boolean + loongarch_elf_finish_dynamic_sections (bfd *output_bfd, + struct bfd_link_info *info) +@@ -3298,8 +3611,6 @@ loongarch_elf_finish_dynamic_sections (bfd *output_bfd, + } + + /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ +- htab_traverse +- (htab->loc_hash_table, elfNN_loongarch_finish_local_dynamic_symbol, info); + + return TRUE; + } +@@ -3589,6 +3900,7 @@ _loongarch_bfd_set_section_contents(bfd *abfd, + #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections + #define elf_backend_relocate_section loongarch_elf_relocate_section + #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol ++#define elf_backend_output_arch_local_syms elf_loongarch_output_arch_local_syms + #define elf_backend_finish_dynamic_sections loongarch_elf_finish_dynamic_sections + #define elf_backend_object_p loongarch_elf_object_p + #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook +diff --git a/bfd/elfxx-loongarch.h b/bfd/elfxx-loongarch.h +index 0e980864..143f6e37 100644 +--- a/bfd/elfxx-loongarch.h ++++ b/bfd/elfxx-loongarch.h +@@ -9,3 +9,11 @@ loongarch_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code); + + extern reloc_howto_type * + loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name); ++ ++/* TRUE if this is a PLT reference to a local IFUNC. */ ++#define PLT_LOCAL_IFUNC_P(INFO, H) \ ++ ((H)->dynindx == -1 \ ++ || ((bfd_link_executable (INFO) \ ++ || ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT) \ ++ && (H)->def_regular \ ++ && (H)->type == STT_GNU_IFUNC)) +-- +2.43.5 + diff --git a/binutils.spec b/binutils.spec index 1d7589c8293a92187217d6d14aa587a61ad47be2..334fc002d6ddb441544a8c64cffa40ff5d7f1ce6 100644 --- a/binutils.spec +++ b/binutils.spec @@ -24,7 +24,7 @@ # /usr/bin/aarch64-linux-gnu-ar # /usr/bin/aarch64-linux-gnu-as # [etc] -%define anolis_release .0.2 +%define anolis_release .0.3 %if 0%{!?binutils_target:1} @@ -655,6 +655,11 @@ Patch1010: Add-missing-opcode-and-3A6000.patch Patch1011: Some-testsuite-fix.patch Patch1012: Always-allocate-a-new-pointer-for-section-name-that-.patch Patch1013: binutils-Remove-ABI_XLP32-related-code.patch +Patch1014: Move-the-dynamic-relocation-of-local-ifunc-from-the-.patch +Patch1015: LoongArch-Add-bad-static-relocation-check.patch +Patch1016: Fix-behavior-of-as-and-ld-when-relocation-overflows.patch +Patch1017: Add-lbt-lvz-support.patch +Patch1018: FCSR-fcsrX.patch #end #---------------------------------------------------------------------------- @@ -914,6 +919,11 @@ using libelf instead of BFD. %patch1011 -p1 %patch1012 -p1 %patch1013 -p1 +%patch1014 -p1 +%patch1015 -p1 +%patch1016 -p1 +%patch1017 -p1 +%patch1018 -p1 # We cannot run autotools as there is an exact requirement of autoconf-2.59. # FIXME - this is no longer true. Maybe try reinstating autotool use ? @@ -1363,6 +1373,14 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Thu Aug 15 2024 Peng Fan - 2.30-123.0.3 + - LoongArch: Sync to 2.31.1-22.4. + - Move the dynamic relocation of local ifunc + - Add bad static relocation check + - Fix behavior of as and ld when overflows + - Add lbt and lvz support + - Fix FCSR-fcsrX + * Thu Mar 07 2024 Peng Fan - 2.30-123.0.2 - LoongArch: Always allocate a new pointer for section name. - LoongArch: binutils Remove ABI_XLP32 related code.