diff --git a/scripts/Makefile b/scripts/Makefile
index 9adb6d247818f1355e2e478256022cd10afd05f2..5d89c2ee274837d4f519dabae9271a2094b46cfb 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -24,10 +24,17 @@ HOSTCFLAGS_extract-cert.o = $(CRYPTO_CFLAGS)
HOSTLDLIBS_extract-cert = $(CRYPTO_LIBS)
ifdef CONFIG_UNWINDER_ORC
+# Additional ARCH settings for x86
ifeq ($(ARCH),x86_64)
ARCH := x86
endif
-HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/x86/include
+
+# Additional ARCH settings for loongarch
+ifeq ($(ARCH),loongarch64)
+ARCH := loongarch
+endif
+
+HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/$(ARCH)/include
HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED
HOSTLDLIBS_sorttable = -lpthread
endif
diff --git a/tools/arch/loongarch/include/uapi/asm/perf_regs.h b/tools/arch/loongarch/include/uapi/asm/perf_regs.h
new file mode 100644
index 0000000000000000000000000000000000000000..9943d418e01d3c47f1a205b4d0c18d3d8a902204
--- /dev/null
+++ b/tools/arch/loongarch/include/uapi/asm/perf_regs.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_LOONGARCH_PERF_REGS_H
+#define _ASM_LOONGARCH_PERF_REGS_H
+
+enum perf_event_loongarch_regs {
+ PERF_REG_LOONGARCH_PC,
+ PERF_REG_LOONGARCH_R1,
+ PERF_REG_LOONGARCH_R2,
+ PERF_REG_LOONGARCH_R3,
+ PERF_REG_LOONGARCH_R4,
+ PERF_REG_LOONGARCH_R5,
+ PERF_REG_LOONGARCH_R6,
+ PERF_REG_LOONGARCH_R7,
+ PERF_REG_LOONGARCH_R8,
+ PERF_REG_LOONGARCH_R9,
+ PERF_REG_LOONGARCH_R10,
+ PERF_REG_LOONGARCH_R11,
+ PERF_REG_LOONGARCH_R12,
+ PERF_REG_LOONGARCH_R13,
+ PERF_REG_LOONGARCH_R14,
+ PERF_REG_LOONGARCH_R15,
+ PERF_REG_LOONGARCH_R16,
+ PERF_REG_LOONGARCH_R17,
+ PERF_REG_LOONGARCH_R18,
+ PERF_REG_LOONGARCH_R19,
+ PERF_REG_LOONGARCH_R20,
+ PERF_REG_LOONGARCH_R21,
+ PERF_REG_LOONGARCH_R22,
+ PERF_REG_LOONGARCH_R23,
+ PERF_REG_LOONGARCH_R24,
+ PERF_REG_LOONGARCH_R25,
+ PERF_REG_LOONGARCH_R26,
+ PERF_REG_LOONGARCH_R27,
+ PERF_REG_LOONGARCH_R28,
+ PERF_REG_LOONGARCH_R29,
+ PERF_REG_LOONGARCH_R30,
+ PERF_REG_LOONGARCH_R31,
+ PERF_REG_LOONGARCH_MAX = PERF_REG_LOONGARCH_R31 + 1,
+};
+#endif /* _ASM_LOONGARCH_PERF_REGS_H */
diff --git a/tools/arch/loongarch/include/uapi/asm/unistd.h b/tools/arch/loongarch/include/uapi/asm/unistd.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3666a55f7a66df540671e42f272c261d353b677
--- /dev/null
+++ b/tools/arch/loongarch/include/uapi/asm/unistd.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Copyright (C) 2020-2021 Loongson Technology Corporation Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#define __ARCH_WANT_NEW_STAT
+#define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_SYS_CLONE3
+
+#include
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index f195e079660f6cb51cd649bf2931e8b9ab1ed707..a93b4b55fd2fcac0f640a3aa57f3a2b102259c33 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -74,6 +74,13 @@ ifeq ($(SRCARCH),arm64)
LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
endif
+ifeq ($(SRCARCH),loongarch)
+ NO_PERF_REGS := 0
+ CFLAGS += -I$(OUTPUT)arch/loongarch/include/generated
+ CFLAGS += -I$(OUTPUT)../arch/loongarch/include/uapi
+ LIBUNWIND_LIBS = -lunwind -lunwind-loongarch
+endif
+
ifeq ($(SRCARCH),riscv)
NO_PERF_REGS := 0
endif
diff --git a/tools/perf/arch/loongarch/Build b/tools/perf/arch/loongarch/Build
new file mode 100644
index 0000000000000000000000000000000000000000..e4e5f33c84d862aaba8e05ded73e0c336d6e90bd
--- /dev/null
+++ b/tools/perf/arch/loongarch/Build
@@ -0,0 +1 @@
+perf-y += util/
diff --git a/tools/perf/arch/loongarch/Makefile b/tools/perf/arch/loongarch/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1229157b09e1e6db3be6986d32ed700ca459ec85
--- /dev/null
+++ b/tools/perf/arch/loongarch/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+endif
+PERF_HAVE_JITDUMP := 1
+
+#
+# Syscall table generation for perf
+#
+
+out := $(OUTPUT)arch/loongarch/include/generated/asm
+header := $(out)/syscalls_64.c
+incpath := $(srctree)/tools
+sysdef := $(srctree)/tools/arch/loongarch/include/uapi/asm/unistd.h
+sysprf := $(srctree)/tools/perf/arch/loongarch/entry/syscalls/
+systbl := $(sysprf)/mksyscalltbl
+
+# Create output directory if not already present
+_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
+
+$(header): $(sysdef) $(systbl)
+ $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
+
+clean::
+ $(call QUIET_CLEAN, loongarch) $(RM) $(header)
+
+archheaders: $(header)
diff --git a/tools/perf/arch/loongarch/annotate/instructions.c b/tools/perf/arch/loongarch/annotate/instructions.c
new file mode 100644
index 0000000000000000000000000000000000000000..206e1fca38a47350cde878f8f40f50039d50e0b6
--- /dev/null
+++ b/tools/perf/arch/loongarch/annotate/instructions.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Perf annotate functions.
+ *
+ * Copyright (C) 2020 Loongson Technology Corporation Limited
+ */
+
+static
+struct ins_ops *loongarch__associate_ins_ops(struct arch *arch, const char *name)
+{
+ struct ins_ops *ops = NULL;
+
+ if (!strncmp(name, "beqz", 4) ||
+ !strncmp(name, "bnez", 4) ||
+ !strncmp(name, "beq", 3) ||
+ !strncmp(name, "bne", 3) ||
+ !strncmp(name, "blt", 3) ||
+ !strncmp(name, "bge", 3) ||
+ !strncmp(name, "bltu", 4) ||
+ !strncmp(name, "bgeu", 4) ||
+ !strncmp(name, "bl", 2))
+ ops = &call_ops;
+ else if (!strncmp(name, "jirl", 4))
+ ops = &ret_ops;
+ else if (name[0] == 'b')
+ ops = &jump_ops;
+ else
+ return NULL;
+
+ arch__associate_ins_ops(arch, name, ops);
+
+ return ops;
+}
+
+static
+int loongarch__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+{
+ if (!arch->initialized) {
+ arch->associate_instruction_ops = loongarch__associate_ins_ops;
+ arch->initialized = true;
+ arch->objdump.comment_char = '#';
+ }
+
+ return 0;
+}
diff --git a/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl b/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
new file mode 100755
index 0000000000000000000000000000000000000000..86dad5a018b73335855428b400656e73cbbc55bf
--- /dev/null
+++ b/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
@@ -0,0 +1,60 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generate system call table for perf. Derived from
+# powerpc script.
+#
+# Copyright (C) 2020 Loongson Technology Co., Ltd.
+# Author(s): Ming Wang
+
+gcc=$1
+hostcc=$2
+incpath=$3
+input=$4
+
+if ! test -r $input; then
+ echo "Could not read input file" >&2
+ exit 1
+fi
+
+create_table_from_c()
+{
+ local sc nr last_sc
+
+ create_table_exe=`mktemp ${TMPDIR:-/tmp}/create-table-XXXXXX`
+
+ {
+
+ cat <<-_EoHEADER
+ #include
+ #include "$input"
+ int main(int argc, char *argv[])
+ {
+ _EoHEADER
+
+ while read sc nr; do
+ printf "%s\n" " printf(\"\\t[%d] = \\\"$sc\\\",\\n\", $nr);"
+ last_sc=$nr
+ done
+
+ printf "%s\n" " printf(\"#define SYSCALLTBL_LOONGARCH_MAX_ID %d\\n\", $last_sc);"
+ printf "}\n"
+
+ } | $hostcc -I $incpath/include/uapi -o $create_table_exe -x c -
+
+ $create_table_exe
+
+ rm -f $create_table_exe
+}
+
+create_table()
+{
+ echo "static const char *syscalltbl_loongarch[] = {"
+ create_table_from_c
+ echo "};"
+}
+
+$gcc -E -dM -x c -I $incpath/include/uapi $input \
+ |sed -ne 's/^#define __NR_//p' \
+ |sort -t' ' -k2 -n \
+ |create_table
diff --git a/tools/perf/arch/loongarch/include/dwarf-regs-table.h b/tools/perf/arch/loongarch/include/dwarf-regs-table.h
new file mode 100644
index 0000000000000000000000000000000000000000..676c54a226a5d56854ea8ed029e87a5a02315d55
--- /dev/null
+++ b/tools/perf/arch/loongarch/include/dwarf-regs-table.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * dwarf-regs-table.h : Mapping of DWARF debug register numbers into
+ * register names.
+ *
+ * Copyright (C) 2020 Loongson Technology Corporation Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+static const char * const loongarch_regstr_tbl[] = {
+ "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
+ "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19",
+ "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "%29",
+ "$30", "$31",
+};
+#endif
diff --git a/tools/perf/arch/loongarch/include/perf_regs.h b/tools/perf/arch/loongarch/include/perf_regs.h
new file mode 100644
index 0000000000000000000000000000000000000000..82d531dcd90fb82b5d63d468f0d36eda88afa6c3
--- /dev/null
+++ b/tools/perf/arch/loongarch/include/perf_regs.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include
+#include
+#include
+
+#define PERF_REGS_MAX PERF_REG_LOONGARCH_MAX
+#define PERF_REG_IP PERF_REG_LOONGARCH_PC
+#define PERF_REG_SP PERF_REG_LOONGARCH_R3
+
+#define PERF_REGS_MASK ((1ULL << PERF_REG_LOONGARCH_MAX) - 1)
+
+static inline const char *__perf_reg_name(int id)
+{
+ switch (id) {
+ case PERF_REG_LOONGARCH_PC:
+ return "PC";
+ case PERF_REG_LOONGARCH_R1:
+ return "$1";
+ case PERF_REG_LOONGARCH_R2:
+ return "$2";
+ case PERF_REG_LOONGARCH_R3:
+ return "$3";
+ case PERF_REG_LOONGARCH_R4:
+ return "$4";
+ case PERF_REG_LOONGARCH_R5:
+ return "$5";
+ case PERF_REG_LOONGARCH_R6:
+ return "$6";
+ case PERF_REG_LOONGARCH_R7:
+ return "$7";
+ case PERF_REG_LOONGARCH_R8:
+ return "$8";
+ case PERF_REG_LOONGARCH_R9:
+ return "$9";
+ case PERF_REG_LOONGARCH_R10:
+ return "$10";
+ case PERF_REG_LOONGARCH_R11:
+ return "$11";
+ case PERF_REG_LOONGARCH_R12:
+ return "$12";
+ case PERF_REG_LOONGARCH_R13:
+ return "$13";
+ case PERF_REG_LOONGARCH_R14:
+ return "$14";
+ case PERF_REG_LOONGARCH_R15:
+ return "$15";
+ case PERF_REG_LOONGARCH_R16:
+ return "$16";
+ case PERF_REG_LOONGARCH_R17:
+ return "$17";
+ case PERF_REG_LOONGARCH_R18:
+ return "$18";
+ case PERF_REG_LOONGARCH_R19:
+ return "$19";
+ case PERF_REG_LOONGARCH_R20:
+ return "$20";
+ case PERF_REG_LOONGARCH_R21:
+ return "$21";
+ case PERF_REG_LOONGARCH_R22:
+ return "$22";
+ case PERF_REG_LOONGARCH_R23:
+ return "$23";
+ case PERF_REG_LOONGARCH_R24:
+ return "$24";
+ case PERF_REG_LOONGARCH_R25:
+ return "$25";
+ case PERF_REG_LOONGARCH_R26:
+ return "$26";
+ case PERF_REG_LOONGARCH_R27:
+ return "$27";
+ case PERF_REG_LOONGARCH_R28:
+ return "$28";
+ case PERF_REG_LOONGARCH_R29:
+ return "$29";
+ case PERF_REG_LOONGARCH_R30:
+ return "$30";
+ case PERF_REG_LOONGARCH_R31:
+ return "$31";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongarch/util/Build
new file mode 100644
index 0000000000000000000000000000000000000000..fab48acf21c59ea02d08d2ceea46ce8ad91e0310
--- /dev/null
+++ b/tools/perf/arch/loongarch/util/Build
@@ -0,0 +1,4 @@
+perf-y += perf_regs.o
+
+perf-$(CONFIG_DWARF) += dwarf-regs.o
+perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
diff --git a/tools/perf/arch/loongarch/util/dwarf-regs.c b/tools/perf/arch/loongarch/util/dwarf-regs.c
new file mode 100644
index 0000000000000000000000000000000000000000..bbd343e3191f8102fca3dcef3fefe21f0229f8d3
--- /dev/null
+++ b/tools/perf/arch/loongarch/util/dwarf-regs.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include
+#include
+
+static const char *loongarch_gpr_names[32] = {
+ "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
+ "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19",
+ "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29",
+ "$30", "$31"
+};
+
+const char *get_arch_regstr(unsigned int n)
+{
+ n %= 32;
+ return loongarch_gpr_names[n];
+}
diff --git a/tools/perf/arch/loongarch/util/perf_regs.c b/tools/perf/arch/loongarch/util/perf_regs.c
new file mode 100644
index 0000000000000000000000000000000000000000..2833e101a7c6407263130e9948a06a2caa32bc4b
--- /dev/null
+++ b/tools/perf/arch/loongarch/util/perf_regs.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "../../../util/perf_regs.h"
+
+const struct sample_reg sample_reg_masks[] = {
+ SMPL_REG_END
+};
diff --git a/tools/perf/arch/loongarch/util/unwind-libunwind.c b/tools/perf/arch/loongarch/util/unwind-libunwind.c
new file mode 100644
index 0000000000000000000000000000000000000000..abcd9e2c6624b7ec376190b205ca4a94a1393acf
--- /dev/null
+++ b/tools/perf/arch/loongarch/util/unwind-libunwind.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include
+#include
+#include "perf_regs.h"
+#include "../../util/unwind.h"
+#include "util/debug.h"
+
+int libunwind__arch_reg_id(int regnum)
+{
+ switch (regnum) {
+ case UNW_LOONGARCH_R1:
+ return PERF_REG_LOONGARCH_R1;
+ case UNW_LOONGARCH_R2:
+ return PERF_REG_LOONGARCH_R2;
+ case UNW_LOONGARCH_R3:
+ return PERF_REG_LOONGARCH_R3;
+ case UNW_LOONGARCH_R4:
+ return PERF_REG_LOONGARCH_R4;
+ case UNW_LOONGARCH_R5:
+ return PERF_REG_LOONGARCH_R5;
+ case UNW_LOONGARCH_R6:
+ return PERF_REG_LOONGARCH_R6;
+ case UNW_LOONGARCH_R7:
+ return PERF_REG_LOONGARCH_R7;
+ case UNW_LOONGARCH_R8:
+ return PERF_REG_LOONGARCH_R8;
+ case UNW_LOONGARCH_R9:
+ return PERF_REG_LOONGARCH_R9;
+ case UNW_LOONGARCH_R10:
+ return PERF_REG_LOONGARCH_R10;
+ case UNW_LOONGARCH_R11:
+ return PERF_REG_LOONGARCH_R11;
+ case UNW_LOONGARCH_R12:
+ return PERF_REG_LOONGARCH_R12;
+ case UNW_LOONGARCH_R13:
+ return PERF_REG_LOONGARCH_R13;
+ case UNW_LOONGARCH_R14:
+ return PERF_REG_LOONGARCH_R14;
+ case UNW_LOONGARCH_R15:
+ return PERF_REG_LOONGARCH_R15;
+ case UNW_LOONGARCH_R16:
+ return PERF_REG_LOONGARCH_R16;
+ case UNW_LOONGARCH_R17:
+ return PERF_REG_LOONGARCH_R17;
+ case UNW_LOONGARCH_R18:
+ return PERF_REG_LOONGARCH_R18;
+ case UNW_LOONGARCH_R19:
+ return PERF_REG_LOONGARCH_R19;
+ case UNW_LOONGARCH_R20:
+ return PERF_REG_LOONGARCH_R20;
+ case UNW_LOONGARCH_R21:
+ return PERF_REG_LOONGARCH_R21;
+ case UNW_LOONGARCH_R22:
+ return PERF_REG_LOONGARCH_R22;
+ case UNW_LOONGARCH_R23:
+ return PERF_REG_LOONGARCH_R23;
+ case UNW_LOONGARCH_R24:
+ return PERF_REG_LOONGARCH_R24;
+ case UNW_LOONGARCH_R25:
+ return PERF_REG_LOONGARCH_R25;
+ case UNW_LOONGARCH_R26:
+ return PERF_REG_LOONGARCH_R26;
+ case UNW_LOONGARCH_R27:
+ return PERF_REG_LOONGARCH_R27;
+ case UNW_LOONGARCH_R28:
+ return PERF_REG_LOONGARCH_R28;
+ case UNW_LOONGARCH_R29:
+ return PERF_REG_LOONGARCH_R29;
+ case UNW_LOONGARCH_R30:
+ return PERF_REG_LOONGARCH_R30;
+ case UNW_LOONGARCH_R31:
+ return PERF_REG_LOONGARCH_R31;
+ case UNW_LOONGARCH_PC:
+ return PERF_REG_LOONGARCH_PC;
+ default:
+ pr_err("unwind: invalid reg id %d\n", regnum);
+ return -EINVAL;
+ }
+
+ return -EINVAL;
+}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 0f225b68d748e1a71b0ff0d65773c16060f8afc7..d2ab62d2c8f38b7e04600b5f8ff56c60a405d75c 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -156,6 +156,7 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i
#include "arch/powerpc/annotate/instructions.c"
#include "arch/s390/annotate/instructions.c"
#include "arch/sparc/annotate/instructions.c"
+#include "arch/loongarch/annotate/instructions.c"
static struct arch architectures[] = {
{
@@ -205,6 +206,13 @@ static struct arch architectures[] = {
.comment_char = '#',
},
},
+ {
+ .name = "loongarch",
+ .init = loongarch__annotate_init,
+ .objdump = {
+ .comment_char = '#',
+ },
+ },
};
static void ins__delete(struct ins_operands *ops)
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 1b49ecee5affd2b19d10ce6790eaa7190e107bc1..43a77aeeb3100730d03504cb8afbe865c33ec751 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -14,6 +14,10 @@
#define EM_AARCH64 183 /* ARM 64 bit */
#endif
+#ifndef EM_LOONGARCH
+#define EM_LOONGARCH 258 /* LoongArch */
+#endif
+
/* Define const char * {arch}_register_tbl[] */
#define DEFINE_DWARF_REGSTR_TABLE
#include "../arch/x86/include/dwarf-regs-table.h"
@@ -24,6 +28,7 @@
#include "../arch/s390/include/dwarf-regs-table.h"
#include "../arch/sparc/include/dwarf-regs-table.h"
#include "../arch/xtensa/include/dwarf-regs-table.h"
+#include "../arch/loongarch/include/dwarf-regs-table.h"
#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
@@ -53,6 +58,8 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
return __get_dwarf_regstr(sparc_regstr_tbl, n);
case EM_XTENSA:
return __get_dwarf_regstr(xtensa_regstr_tbl, n);
+ case EM_LOONGARCH:
+ return __get_dwarf_regstr(loongarch_regstr_tbl, n);
default:
pr_err("ELF MACHINE %x is not supported.\n", machine);
}
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index f243d9acf943b5b52de32af1f8de967e06521e45..abbab063616f51dcfdfefa7503ec42ec06786fc1 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -347,6 +347,8 @@ static const char *normalize_arch(char *arch)
return "mips";
if (!strncmp(arch, "sh", 2) && isdigit(arch[2]))
return "sh";
+ if (!strncmp(arch, "loongarch", 9))
+ return "loongarch";
return arch;
}
diff --git a/tools/perf/util/genelf.h b/tools/perf/util/genelf.h
index ac638945b4cb095e85659b76cf40b40687d6e60e..43dac6998d2b5d02dae4a40de3a89190ca660101 100644
--- a/tools/perf/util/genelf.h
+++ b/tools/perf/util/genelf.h
@@ -38,6 +38,9 @@ int jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_ent
#elif defined(__s390x__)
#define GEN_ELF_ARCH EM_S390
#define GEN_ELF_CLASS ELFCLASS64
+#elif defined(__loongarch__)
+#define GEN_ELF_ARCH EM_LOONGARCH
+#define GEN_ELF_CLASS ELFCLASS64
#else
#error "unsupported architecture"
#endif
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index df515cd8d01846f156e5c971d30649b54579e0f6..94affad8310137b32c9a4e448094327441fe9a91 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -16,6 +16,7 @@
#include "map_symbol.h"
#include "branch.h"
#include "mem-events.h"
+#include "path.h"
#include "srcline.h"
#include "symbol.h"
#include "sort.h"
@@ -1379,7 +1380,7 @@ static int maps__set_modules_path_dir(struct maps *maps, const char *dir_name, i
struct stat st;
/*sshfs might return bad dent->d_type, so we have to stat*/
- snprintf(path, sizeof(path), "%s/%s", dir_name, dent->d_name);
+ path__join(path, sizeof(path), dir_name, dent->d_name);
if (stat(path, &st))
continue;
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 03bd99d3be16f352cc7ae09d304340d9a8b2cb87..e441f12c7272274abea56c926274e22e50eada9b 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -34,6 +34,10 @@ static const char **syscalltbl_native = syscalltbl_powerpc_32;
#include
const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
static const char **syscalltbl_native = syscalltbl_arm64;
+#elif defined(__loongarch__)
+#include
+const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
+static const char **syscalltbl_native = syscalltbl_loongarch;
#endif
struct syscall {
diff --git a/tools/scripts/Makefile.arch b/tools/scripts/Makefile.arch
index b10b7a27c33fd16b10fa3d7fcfd7a5fa372f2d59..0b2af44c167fcc6a2b1faeecb935f32f9dc1db57 100644
--- a/tools/scripts/Makefile.arch
+++ b/tools/scripts/Makefile.arch
@@ -4,7 +4,8 @@ HOSTARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
-e /arm64/!s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
- -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
+ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
+ -e s/loongarch.*/loongarch/)
ifndef ARCH
ARCH := $(HOSTARCH)
@@ -33,6 +34,15 @@ ifeq ($(ARCH),sh64)
SRCARCH := sh
endif
+# Additional ARCH settings for loongarch
+ifeq ($(ARCH),loongarch32)
+ SRCARCH := loongarch
+endif
+
+ifeq ($(ARCH),loongarch64)
+ SRCARCH := loongarch
+endif
+
LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1)
ifeq ($(LP64), 1)
IS_64_BIT := 1