Skip to content

Commit

Permalink
LoongArch: Update ELF e_flags handling according to specification.
Browse files Browse the repository at this point in the history
  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]: loongson/LoongArch-Documentation#61
  [3]: loongson/LoongArch-Documentation#47
  • Loading branch information
lzshhxx committed Sep 30, 2022
1 parent 0d94a87 commit c4a7e6b
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 41 deletions.
21 changes: 18 additions & 3 deletions bfd/elfnn-loongarch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
10 changes: 5 additions & 5 deletions binutils/readelf.c
Original file line number Diff line number Diff line change
Expand Up @@ -4343,18 +4343,18 @@ 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))
strcat (buf, ", SINGLE-FLOAT");
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;
}
}
Expand Down
20 changes: 10 additions & 10 deletions gas/config/tc-loongarch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand Down
44 changes: 21 additions & 23 deletions include/elf/loongarch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit c4a7e6b

Please sign in to comment.