Match most appropriate base platform string based on insn_flags.
Logic is aligned with arch/mips/kernel/cpu-probe.c in Linux kernel.
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
linux-user/elfload.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index e7666c5c60..8a4ac9787f 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1050,6 +1050,37 @@ static uint32_t get_elf_hwcap(void)
#define elf_check_abi(x) (!((x) & EF_MIPS_ABI2))
#endif
+#define ELF_BASE_PLATFORM get_elf_base_platform()
+
+#define MATCH_PLATFORM_INSN(_flags, _base_platform) \
+ do { if ((cpu->env.insn_flags & (_flags)) == _flags) \
+ { return _base_platform; } } while (0)
+
+static const char *get_elf_base_platform(void)
+{
+ MIPSCPU *cpu = MIPS_CPU(thread_cpu);
+
+ /* 64 bit ISAs goes first */
+ MATCH_PLATFORM_INSN(CPU_MIPS64R6, "mips64r6");
+ MATCH_PLATFORM_INSN(CPU_MIPS64R5, "mips64r5");
+ MATCH_PLATFORM_INSN(CPU_MIPS64R2, "mips64r2");
+ MATCH_PLATFORM_INSN(CPU_MIPS64R1, "mips64");
+ MATCH_PLATFORM_INSN(CPU_MIPS5, "mips5");
+ MATCH_PLATFORM_INSN(CPU_MIPS4, "mips4");
+ MATCH_PLATFORM_INSN(CPU_MIPS3, "mips3");
+
+ /* 32 bit ISAs */
+ MATCH_PLATFORM_INSN(CPU_MIPS32R6, "mips32r6");
+ MATCH_PLATFORM_INSN(CPU_MIPS32R5, "mips32r5");
+ MATCH_PLATFORM_INSN(CPU_MIPS32R2, "mips32r2");
+ MATCH_PLATFORM_INSN(CPU_MIPS32R1, "mips32");
+ MATCH_PLATFORM_INSN(CPU_MIPS2, "mips2");
+
+ /* Fallback */
+ return "mips";
+}
+#undef MATCH_PLATFORM_INSN
+
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
--
2.32.1 (Apple Git-133)
On 1/8/22 22:09, Jiaxun Yang wrote:
"On MIPS, AT_BASE_PLATFORM identifies the ISA level (since Linux 5.7)."
> Match most appropriate base platform string based on insn_flags.
> Logic is aligned with arch/mips/kernel/cpu-probe.c in Linux kernel.
"... aligned with set_isa() from ..."
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
> linux-user/elfload.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index e7666c5c60..8a4ac9787f 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -1050,6 +1050,37 @@ static uint32_t get_elf_hwcap(void)
> #define elf_check_abi(x) (!((x) & EF_MIPS_ABI2))
> #endif
>
> +#define ELF_BASE_PLATFORM get_elf_base_platform()
> +
> +#define MATCH_PLATFORM_INSN(_flags, _base_platform) \
> + do { if ((cpu->env.insn_flags & (_flags)) == _flags) \
> + { return _base_platform; } } while (0)
> +
> +static const char *get_elf_base_platform(void)
> +{
> + MIPSCPU *cpu = MIPS_CPU(thread_cpu);
> +
> + /* 64 bit ISAs goes first */
> + MATCH_PLATFORM_INSN(CPU_MIPS64R6, "mips64r6");
> + MATCH_PLATFORM_INSN(CPU_MIPS64R5, "mips64r5");
> + MATCH_PLATFORM_INSN(CPU_MIPS64R2, "mips64r2");
> + MATCH_PLATFORM_INSN(CPU_MIPS64R1, "mips64");
> + MATCH_PLATFORM_INSN(CPU_MIPS5, "mips5");
> + MATCH_PLATFORM_INSN(CPU_MIPS4, "mips4");
> + MATCH_PLATFORM_INSN(CPU_MIPS3, "mips3");
> +
> + /* 32 bit ISAs */
> + MATCH_PLATFORM_INSN(CPU_MIPS32R6, "mips32r6");
> + MATCH_PLATFORM_INSN(CPU_MIPS32R5, "mips32r5");
> + MATCH_PLATFORM_INSN(CPU_MIPS32R2, "mips32r2");
> + MATCH_PLATFORM_INSN(CPU_MIPS32R1, "mips32");
> + MATCH_PLATFORM_INSN(CPU_MIPS2, "mips2");
> +
> + /* Fallback */
> + return "mips";
> +}
> +#undef MATCH_PLATFORM_INSN
> +
> static inline void init_thread(struct target_pt_regs *regs,
> struct image_info *infop)
> {
© 2016 - 2026 Red Hat, Inc.