From c4a7e6b56218e1d5a858682186b542e2eae01a4a Mon Sep 17 00:00:00 2001 From: liuzhensong Date: Thu, 4 Aug 2022 14:30:39 +0800 Subject: [PATCH] LoongArch: Update ELF e_flags handling according to specification. Update handling of e_flags according to the documentation update [1] (discussions [2][3]). Object file bitness is now represented in the EI_CLASS byte. The e_flags field is now interpreted as follows: e_flags[2:0]: Base ABI modifier - 0x1: soft-float - 0x2: single-precision hard-float - 0x3: double-precision hard-float e_flags[7:6]: ELF object ABI version - 0x0: v0 - 0x1: v1 [1]: https://github.com/loongson/LoongArch-Documentation/blob/main/docs/LoongArch-ELF-ABI-EN.adoc#e_flags-identifies-abi-type-and-version [2]: https://github.com/loongson/LoongArch-Documentation/pull/61 [3]: https://github.com/loongson/LoongArch-Documentation/pull/47 --- bfd/elfnn-loongarch.c | 21 ++++++++++++++++--- binutils/readelf.c | 10 ++++----- gas/config/tc-loongarch.c | 20 +++++++++--------- include/elf/loongarch.h | 44 +++++++++++++++++++-------------------- 4 files changed, 54 insertions(+), 41 deletions(-) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 33c85e5207c..c040c5b4ec8 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -416,8 +416,22 @@ elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) elf_elfheader (obfd)->e_flags = in_flags; return true; } + else if (out_flags != in_flags) + { + if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags) + && EF_LOONGARCH_IS_OBJ_V1 (in_flags)) + || (EF_LOONGARCH_IS_OBJ_V0 (in_flags) + && EF_LOONGARCH_IS_OBJ_V1 (out_flags))) + { + elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1; + out_flags = elf_elfheader (obfd)->e_flags; + in_flags = out_flags; + } + } /* Disallow linking different ABIs. */ + /* Only check relocation version. + The obj_v0 is compatible with obj_v1. */ if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK) { _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd); @@ -1579,15 +1593,16 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd, if (bfd_link_executable (info) && !info->nointerp) { const char *interpreter; - flagword flags = elf_elfheader (output_bfd)->e_flags; s = bfd_get_linker_section (dynobj, ".interp"); BFD_ASSERT (s != NULL); - if (EF_LOONGARCH_IS_ILP32 (flags)) + + if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32) interpreter = "/lib32/ld.so.1"; - else if (EF_LOONGARCH_IS_LP64 (flags)) + else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64) interpreter = "/lib64/ld.so.1"; else interpreter = "/lib/ld.so.1"; + s->contents = (unsigned char *) interpreter; s->size = strlen (interpreter) + 1; } diff --git a/binutils/readelf.c b/binutils/readelf.c index b1dbcad06f5..351571c8abb 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -4343,11 +4343,6 @@ get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine) } break; case EM_LOONGARCH: - if (EF_LOONGARCH_IS_LP64 (e_flags)) - strcat (buf, ", LP64"); - else if (EF_LOONGARCH_IS_ILP32 (e_flags)) - strcat (buf, ", ILP32"); - if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags)) strcat (buf, ", SOFT-FLOAT"); else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags)) @@ -4355,6 +4350,11 @@ get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine) else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags)) strcat (buf, ", DOUBLE-FLOAT"); + if (EF_LOONGARCH_IS_OBJ_V0 (e_flags)) + strcat (buf, ", OBJ-v0"); + else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags)) + strcat (buf, ", OBJ-v1"); + break; } } diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index 5bb8d317c5a..60149a6d8db 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -143,13 +143,13 @@ md_parse_option (int c, const char *arg) char ilp32[256] = ""; unsigned char *suf = (unsigned char *)arg; - lp64['s'] = lp64['S'] = EF_LOONGARCH_ABI_LP64_SOFT_FLOAT; - lp64['f'] = lp64['F'] = EF_LOONGARCH_ABI_LP64_SINGLE_FLOAT; - lp64['d'] = lp64['D'] = EF_LOONGARCH_ABI_LP64_DOUBLE_FLOAT; + lp64['s'] = lp64['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT; + lp64['f'] = lp64['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT; + lp64['d'] = lp64['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT; - ilp32['s'] = ilp32['S'] = EF_LOONGARCH_ABI_ILP32_SOFT_FLOAT; - ilp32['f'] = ilp32['F'] = EF_LOONGARCH_ABI_ILP32_SINGLE_FLOAT; - ilp32['d'] = ilp32['D'] = EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT; + ilp32['s'] = ilp32['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT; + ilp32['f'] = ilp32['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT; + ilp32['d'] = ilp32['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT; switch (c) { @@ -216,24 +216,24 @@ void loongarch_after_parse_args () { /* Set default ABI/ISA LP64D. */ - if (!EF_LOONGARCH_IS_LP64(LARCH_opts.ase_abi) - && !EF_LOONGARCH_IS_ILP32(LARCH_opts.ase_abi)) + if (!LARCH_opts.ase_ilp32) { if (strcmp (default_arch, "loongarch64") == 0) { - LARCH_opts.ase_abi = EF_LOONGARCH_ABI_LP64_DOUBLE_FLOAT; + LARCH_opts.ase_abi = EF_LOONGARCH_ABI_DOUBLE_FLOAT; LARCH_opts.ase_ilp32 = 1; LARCH_opts.ase_lp64 = 1; } else if (strcmp (default_arch, "loongarch32") == 0) { - LARCH_opts.ase_abi = EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT; + LARCH_opts.ase_abi = EF_LOONGARCH_ABI_DOUBLE_FLOAT; LARCH_opts.ase_ilp32 = 1; } else as_bad ("unknown default architecture `%s'", default_arch); } + LARCH_opts.ase_abi |= EF_LOONGARCH_OBJABI_V1; /* Set default ISA double-float. */ if (!LARCH_opts.ase_nf && !LARCH_opts.ase_sf diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h index 74757b82ca8..a6341b46791 100644 --- a/include/elf/loongarch.h +++ b/include/elf/loongarch.h @@ -232,36 +232,34 @@ RELOC_NUMBER (R_LARCH_RELAX, 100) END_RELOC_NUMBERS (R_LARCH_count) /* Processor specific flags for the ELF header e_flags field. */ -/*The flag lp64s/lp64f/lp64d/ilp32s/ilp32f/ilp32d 3bits. */ -#define EF_LOONGARCH_ABI_LP64_SOFT_FLOAT 0x1 -#define EF_LOONGARCH_ABI_LP64_SINGLE_FLOAT 0x2 -#define EF_LOONGARCH_ABI_LP64_DOUBLE_FLOAT 0x3 +/* Base ABI modifier, 3bits. */ +#define EF_LOONGARCH_ABI_SOFT_FLOAT 0x1 +#define EF_LOONGARCH_ABI_SINGLE_FLOAT 0x2 +#define EF_LOONGARCH_ABI_DOUBLE_FLOAT 0x3 +#define EF_LOONGARCH_ABI_MODIFIER_MASK 0x7 -#define EF_LOONGARCH_ABI_ILP32_SOFT_FLOAT 0x5 -#define EF_LOONGARCH_ABI_ILP32_SINGLE_FLOAT 0x6 -#define EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT 0x7 +#define EF_LOONGARCH_OBJABI_V1 0x40 +#define EF_LOONGARCH_OBJABI_MASK 0xC0 -#define EF_LOONGARCH_ABI_MASK 0x7 -#define EF_LOONGARCH_ABI_ILP32_MASK 0x4 -#define EF_LOONGARCH_ABI_FLOAT_MASK 0x3 -#define EF_LOONGARCH_ABI_SOFT_FLOAT_MASK 0x1 -#define EF_LOONGARCH_ABI_SINGLE_FLOAT_MASK 0x2 -#define EF_LOONGARCH_ABI_DOUBLE_FLOAT_MASK 0x3 +#define EF_LOONGARCH_ABI_MASK \ + (EF_LOONGARCH_OBJABI_MASK | EF_LOONGARCH_ABI_MODIFIER_MASK) -#define EF_LOONGARCH_ABI(abi) (EF_LOONGARCH_ABI_MASK & (abi)) +#define EF_LOONGARCH_ABI_MODIFIER(abi) \ + (EF_LOONGARCH_ABI_MODIFIER_MASK & (abi)) +#define EF_LOONGARCH_OBJABI(abi) \ + (EF_LOONGARCH_OBJABI_MASK & (abi)) -#define EF_LOONGARCH_IS_LP64(abi) \ - (EF_LOONGARCH_ABI(abi) && (!(EF_LOONGARCH_ABI(abi) & EF_LOONGARCH_ABI_ILP32_MASK))) -#define EF_LOONGARCH_IS_ILP32(abi) \ - (EF_LOONGARCH_ABI(abi) && (EF_LOONGARCH_ABI(abi) & EF_LOONGARCH_ABI_ILP32_MASK)) +#define EF_LOONGARCH_ABI(abi) ((abi) & EF_LOONGARCH_ABI_MASK) #define EF_LOONGARCH_IS_SOFT_FLOAT(abi) \ - (!((EF_LOONGARCH_ABI(abi) & EF_LOONGARCH_ABI_FLOAT_MASK) ^ EF_LOONGARCH_ABI_SOFT_FLOAT_MASK)) - + (EF_LOONGARCH_ABI_MODIFIER (abi) == EF_LOONGARCH_ABI_SOFT_FLOAT) #define EF_LOONGARCH_IS_SINGLE_FLOAT(abi) \ - (!((EF_LOONGARCH_ABI(abi) & EF_LOONGARCH_ABI_FLOAT_MASK) ^ EF_LOONGARCH_ABI_SINGLE_FLOAT_MASK)) - + (EF_LOONGARCH_ABI_MODIFIER (abi) == EF_LOONGARCH_ABI_SINGLE_FLOAT) #define EF_LOONGARCH_IS_DOUBLE_FLOAT(abi) \ - (!((EF_LOONGARCH_ABI(abi) & EF_LOONGARCH_ABI_FLOAT_MASK) ^ EF_LOONGARCH_ABI_DOUBLE_FLOAT_MASK)) + (EF_LOONGARCH_ABI_MODIFIER (abi) == EF_LOONGARCH_ABI_DOUBLE_FLOAT) + +#define EF_LOONGARCH_IS_OBJ_V0(abi) (!EF_LOONGARCH_OBJABI (abi)) +#define EF_LOONGARCH_IS_OBJ_V1(abi) \ + (EF_LOONGARCH_OBJABI (abi) == EF_LOONGARCH_OBJABI_V1) #endif /* _ELF_LOONGARCH_H */ -- 2.30.2