[PATCH v3 0/6] Add support for MIPS

2024-03-05 Thread Ying Huang
Pass all previous test cases that failed due to MIPS non-support.
The following are the test results on mips64el:
# TOTAL: 274
# PASS:  267
# SKIP:  7
# XFAIL: 0
# FAIL:  0
# XPASS: 0
# ERROR: 0


[PATCH v3 1/6] Support Mips architecture

2024-03-05 Thread Ying Huang
From: Ying Huang 

Signed-off-by: Ying Huang 
---
 backends/Makefile.am|   6 +-
 backends/mips_init.c|  52 
 backends/mips_reloc.def |  93 +++
 backends/mips_symbol.c  |  63 +
 libebl/eblopenbackend.c |   2 +
 libelf/libelfP.h|   3 +
 tests/libelf.h  | 541 
 7 files changed, 758 insertions(+), 2 deletions(-)
 create mode 100644 backends/mips_init.c
 create mode 100644 backends/mips_reloc.def
 create mode 100644 backends/mips_symbol.c
 create mode 100644 tests/libelf.h

diff --git a/backends/Makefile.am b/backends/Makefile.am
index bbb2aac7..b946fd30 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -37,7 +37,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \
 noinst_LIBRARIES = libebl_backends.a libebl_backends_pic.a
 
 modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \
- m68k bpf riscv csky loongarch arc
+ m68k bpf riscv csky loongarch arc mips
 
 i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \
i386_retval.c i386_regs.c i386_auxv.c \
@@ -102,12 +102,14 @@ loongarch_SRCS = loongarch_init.c loongarch_symbol.c 
loongarch_cfi.c \
 
 arc_SRCS = arc_init.c arc_symbol.c
 
+mips_SRCS = mips_init.c mips_symbol.c
+
 libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \
$(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \
$(aarch64_SRCS) $(sparc_SRCS) $(ppc_SRCS) \
$(ppc64_SRCS) $(s390_SRCS) \
$(m68k_SRCS) $(bpf_SRCS) $(riscv_SRCS) $(csky_SRCS) 
\
-   $(loongarch_SRCS) $(arc_SRCS)
+   $(loongarch_SRCS) $(arc_SRCS) $(mips_SRCS)
 
 libebl_backends_pic_a_SOURCES =
 am_libebl_backends_pic_a_OBJECTS = $(libebl_backends_a_SOURCES:.c=.os)
diff --git a/backends/mips_init.c b/backends/mips_init.c
new file mode 100644
index ..cedd08ca
--- /dev/null
+++ b/backends/mips_init.c
@@ -0,0 +1,52 @@
+/* Initialization of MIPS specific backend library.
+   Copyright (C) 2024 CIP United Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * 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
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see .  */
+
+#ifdef HAVE_CONFIG_H
+# include 
+#endif
+
+#define BACKENDmips_
+#define RELOC_PREFIX   R_MIPS_
+#include "libebl_CPU.h"
+#include "libelfP.h"
+
+#define RELOC_TYPE_ID(type) ((type) & 0xff)
+
+/* This defines the common reloc hooks based on mips_reloc.def.  */
+#include "common-reloc.c"
+
+Ebl *
+mips_init (Elf *elf __attribute__ ((unused)),
+  GElf_Half machine __attribute__ ((unused)),
+  Ebl *eh)
+{
+  /* We handle it.  */
+  mips_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  return eh;
+}
diff --git a/backends/mips_reloc.def b/backends/mips_reloc.def
new file mode 100644
index ..5120980c
--- /dev/null
+++ b/backends/mips_reloc.def
@@ -0,0 +1,93 @@
+/* List the relocation types for MIPS.  -*- C -*-
+   Copyright (C) 2024 CIP United Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * 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
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see .  */
+
+/* NAME,   REL|EXEC|DYN*/
+
+
+RELOC_TYPE (NONE,  REL

[PATCH v3 3/6] readelf: Adapt src/readelf -h/-S/-r/-w/-l/-d/-a on mips

2024-03-05 Thread Ying Huang
From: Ying Huang 

-h: support show Flags name
-S: support show mips related section type
-r: support show type of Relocation section
-w: can work and can show correct "strp" contents
-l: support show mips related program header entry type
-d: can show mips related Dynamic type name
-a: support show complete Object attribute section ".gnu.attributes"

Also add test/run-readelf-reloc.sh file to test new type2/type3 of
src/readelf -r.

Signed-off-by: Ying Huang 
---
 backends/Makefile.am   |   2 +-
 backends/mips_attrs.c  | 140 +
 backends/mips_init.c   |   7 +
 backends/mips_symbol.c | 571 +
 libelf/libelfP.h   |   1 +
 src/readelf.c  | 188 +---
 tests/Makefile.am  |   5 +-
 tests/run-readelf-reloc.sh |  42 +++
 8 files changed, 907 insertions(+), 49 deletions(-)
 create mode 100644 backends/mips_attrs.c
 create mode 100755 tests/run-readelf-reloc.sh

diff --git a/backends/Makefile.am b/backends/Makefile.am
index b946fd30..ad95526e 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -102,7 +102,7 @@ loongarch_SRCS = loongarch_init.c loongarch_symbol.c 
loongarch_cfi.c \
 
 arc_SRCS = arc_init.c arc_symbol.c
 
-mips_SRCS = mips_init.c mips_symbol.c
+mips_SRCS = mips_init.c mips_symbol.c mips_attrs.c
 
 libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \
$(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \
diff --git a/backends/mips_attrs.c b/backends/mips_attrs.c
new file mode 100644
index ..54fd3ce3
--- /dev/null
+++ b/backends/mips_attrs.c
@@ -0,0 +1,140 @@
+/* Object attribute tags for MIPS.
+   Copyright (C) 2024 CIP United Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * 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
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see .  */
+
+#ifdef HAVE_CONFIG_H
+# include 
+#endif
+
+#include 
+#include 
+
+#define BACKEND mips_
+#include "libebl_CPU.h"
+
+#define KNOWN_VALUES(...) do   \
+  {\
+static const char *table[] = { __VA_ARGS__ };  \
+if (value < sizeof table / sizeof table[0])\
+  *value_name = table[value];  \
+  } while (0)
+
+//copy gnu attr tags from binutils-2.34/elfcpp/mips.h
+/* Object attribute tags.  */
+enum
+{
+  /* 0-3 are generic.  */
+
+  /* Floating-point ABI used by this object file.  */
+  Tag_GNU_MIPS_ABI_FP = 4,
+
+  /* MSA ABI used by this object file.  */
+  Tag_GNU_MIPS_ABI_MSA = 8,
+};
+
+/* Object attribute values.  */
+enum
+{
+  /* Values defined for Tag_GNU_MIPS_ABI_MSA.  */
+
+  /* Not tagged or not using any ABIs affected by the differences.  */
+  Val_GNU_MIPS_ABI_MSA_ANY = 0,
+
+  /* Using 128-bit MSA.  */
+  Val_GNU_MIPS_ABI_MSA_128 = 1,
+};
+
+/* Object attribute values.  */
+enum
+{
+  /* This is reserved for backward-compatibility with an earlier
+ implementation of the MIPS NaN2008 functionality.  */
+  Val_GNU_MIPS_ABI_FP_NAN2008 = 8,
+};
+
+/* copy binutils-2.34/binutils/readelf.c display_mips_gnu_attribute */
+bool
+mips_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
+   const char *vendor, int tag, uint64_t value,
+   const char **tag_name, const char **value_name)
+{
+  if (!strcmp (vendor, "gnu"))
+switch (tag)
+  {
+  case Tag_GNU_MIPS_ABI_FP:
+   *tag_name = "Tag_GNU_MIPS_ABI_FP";
+   switch (value)
+   {
+ case Val_GNU_MIPS_ABI_FP_ANY:
+   *value_name = "Hard or soft float";
+   return true;
+ case Val_GNU_MIPS_ABI_FP_DOUBLE:
+   *value_name = "Hard float (double precision)";
+   return true;
+ case Val_GNU_MIPS_ABI_FP_SINGLE:
+   *value_name = "Hard float (single precision)";
+   return true;
+ case Val_GNU_MIPS_ABI_FP_SOFT:
+   *value_name = "Soft float";
+   return true;
+ case Val_GNU_MIPS_ABI_FP_OLD_64:
+   *value_name = "Hard float (MIPS32r2 64-bit FPU 12 callee-saved)";
+   return true;
+ case Val_GNU_M

[PATCH v3 2/6] strip: Adapt src/strip -o -f on mips

2024-03-05 Thread Ying Huang
From: Ying Huang 

In mips64 little-endian, r_info consists of four byte fields(contains
three reloc types) and a 32-bit symbol index. In order to adapt
GELF_R_SYM and GELF_R_TYPE, need convert raw data to get correct symbol
index and type.

  libelf/elf_getdata.c: Some eu-utils use read-mmap method to map file,
so we need to malloc and memcpy raw data to avoid segment fault. After
modification, the correct value are saved in the malloced memory not in
process address space.
  libelf/elf_updata.c: Because we converted the relocation info in mips
order when we call elf_getdata.c, so we need to convert the modified data
in original order bits before writing the data to the file.

Signed-off-by: Ying Huang 
---
 libelf/elf_getdata.c | 132 ++-
 libelf/elf_update.c  |  53 +
 2 files changed, 183 insertions(+), 2 deletions(-)

diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 7c3ac043..942ba536 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -133,6 +133,119 @@ __libelf_data_type (GElf_Ehdr *ehdr, int sh_type, 
GElf_Xword align)
 }
 }
 
+/* Convert the data in the current section.  */
+static void
+convert_data_for_mips64el (Elf_Scn *scn, int eclass,
+ int data, size_t size, Elf_Type type)
+{
+  /* Do we need to convert the data and/or adjust for alignment?  */
+  if (data == MY_ELFDATA || type == ELF_T_BYTE)
+{
+  /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to 
convert
+   relocation info(raw data). Some eu-utils use read-mmap method to map 
file, so
+   we need to malloc and memcpy raw data to avoid segment fault. After 
modification,
+   the correct value are saved in the malloced memory not in process 
address space. */
+  scn->data_base = malloc (size);
+  if (scn->data_base == NULL)
+   {
+  __libelf_seterrno (ELF_E_NOMEM);
+ return;
+   }
+
+  /* The copy will be appropriately aligned for direct access.  */
+  memcpy (scn->data_base, scn->rawdata_base, size);
+}
+  else
+{
+  xfct_t fp;
+
+  scn->data_base = malloc (size);
+  if (scn->data_base == NULL)
+   {
+ __libelf_seterrno (ELF_E_NOMEM);
+ return;
+   }
+
+  /* Make sure the source is correctly aligned for the conversion
+function to directly access the data elements.  */
+  char *rawdata_source;
+  /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to 
convert
+   relocation info(raw data). Some eu-utils use read-mmap method to map 
file, so
+   we need to malloc and memcpy raw data to avoid segment fault. After 
modification,
+   the correct value are saved in the malloced memory not in process 
address space. */
+  rawdata_source = malloc (size);
+  if (rawdata_source == NULL)
+   {
+ __libelf_seterrno (ELF_E_NOMEM);
+ return;
+   }
+
+  /* The copy will be appropriately aligned for direct access.  */
+  memcpy (rawdata_source, scn->rawdata_base, size);
+
+  /* Get the conversion function.  */
+  fp = __elf_xfctstom[eclass - 1][type];
+
+  fp (scn->data_base, rawdata_source, size, 0);
+
+  if (rawdata_source != scn->rawdata_base)
+   free (rawdata_source);
+}
+
+  scn->data_list.data.d.d_buf = scn->data_base;
+  scn->data_list.data.d.d_size = size;
+  scn->data_list.data.d.d_type = type;
+  scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
+  scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
+  scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
+
+  scn->data_list.data.s = scn;
+
+  /* In mips64 little-endian, r_info consists of four byte fields(contains
+ three reloc types) and a 32-bit symbol index. In order to adapt
+ GELF_R_SYM and GELF_R_TYPE, need to convert r_info to get correct symbol
+ index and type. */
+  /* references:
+ https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf
+ Page40 && Page41 */
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr->sh_type == SHT_REL)
+{
+  size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CURRENT);
+  int nentries = shdr->sh_size / sh_entsize;
+  for (int cnt = 0; cnt < nentries; ++cnt)
+   {
+ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) &scn->data_list.data.d;
+ Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
+ Elf64_Xword info = value->r_info;
+ value->r_info = (((info & 0x) << 32)
+   | ((info >> 56) & 0xff)
+   | ((info >> 40) & 0xff00)
+   | ((info >> 24) & 0xff)
+   | ((info >> 8) & 0xff00));
+ ((Elf64_Rel *) data_scn->d.d_buf)[cnt] = *value;
+   }
+}
+else if (shdr->sh_type == SHT_RELA)
+  {
+   size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_RELA, 1, EV_CURRENT);
+   int nentries

[PATCH v3 4/6] elflint: adapt src/elflint --gnu src/nm on mips

2024-03-05 Thread Ying Huang
From: Ying Huang 

The errors were:
$ src/elflint --gnu src/nm
section [ 2] '.MIPS.options' contains unknown flag(s) 0x800
section [ 7] '.dynsym': symbol 165 (_DYNAMIC_LINKING): non-local section symbol
section [24] '.got' contains invalid processor-specific flag(s) 0x1000
section [25] '.sdata' contains invalid processor-specific flag(s) 0x1000
section [29] '.debug_aranges' has wrong type: expected PROGBITS, is MIPS_DWARF
section [30] '.debug_info' has wrong type: expected PROGBITS, is MIPS_DWARF
section [31] '.debug_abbrev' has wrong type: expected PROGBITS, is MIPS_DWARF
section [32] '.debug_line' has wrong type: expected PROGBITS, is MIPS_DWARF
section [33] '.debug_frame' has wrong type: expected PROGBITS, is MIPS_DWARF
section [34] '.debug_str' has wrong type: expected PROGBITS, is MIPS_DWARF
section [35] '.debug_loc' has wrong type: expected PROGBITS, is MIPS_DWARF
section [36] '.debug_ranges' has wrong type: expected PROGBITS, is MIPS_DWARF
section [38] '.symtab': symbol 785 (_gp): st_value out of bounds
section [38] '.symtab': symbol 910 (_fbss): st_value out of bounds
section [38] '.symtab': symbol 1051 (_DYNAMIC_LINKING): non-local section symbol

After fixing:
$ src/elflint --gnu src/nm
No errors

Signed-off-by: Ying Huang 
---
 backends/mips_init.c   |  3 +++
 backends/mips_symbol.c | 37 +
 src/elflint.c  | 26 +-
 3 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/backends/mips_init.c b/backends/mips_init.c
index 6b9bd4c8..521e6e51 100644
--- a/backends/mips_init.c
+++ b/backends/mips_init.c
@@ -51,9 +51,12 @@ mips_init (Elf *elf __attribute__ ((unused)),
   HOOK (eh, section_type_name);
   HOOK (eh, machine_flag_check);
   HOOK (eh, machine_flag_name);
+  HOOK (eh, machine_section_flag_check);
   HOOK (eh, segment_type_name);
   HOOK (eh, dynamic_tag_check);
   HOOK (eh, dynamic_tag_name);
   HOOK (eh, check_object_attribute);
+  HOOK (eh, check_special_symbol);
+  HOOK (eh, check_reloc_target_type);
   return eh;
 }
diff --git a/backends/mips_symbol.c b/backends/mips_symbol.c
index 1545fc4b..af4b6e45 100644
--- a/backends/mips_symbol.c
+++ b/backends/mips_symbol.c
@@ -158,6 +158,43 @@ mips_section_type_name (int type,
   return NULL;
 }
 
+bool
+mips_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word 
sh_type)
+{
+  return (sh_type == SHT_MIPS_DWARF);
+}
+
+/* Check whether given symbol's st_value and st_size are OK despite failing
+   normal checks.  */
+bool
+mips_check_special_symbol (Elf *elf,
+   const GElf_Sym *sym __attribute__ ((unused)),
+   const char *name __attribute__ ((unused)),
+   const GElf_Shdr *destshdr)
+{
+  size_t shstrndx;
+  if (elf_getshdrstrndx (elf, &shstrndx) != 0)
+return false;
+  const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name);
+  if (sname == NULL)
+return false;
+  return (strcmp (sname, ".got") == 0 || strcmp (sname, ".bss") == 0);
+}
+
+/* Check whether SHF_MASKPROC flags are valid.  */
+bool
+mips_machine_section_flag_check (GElf_Xword sh_flags)
+{
+  return ((sh_flags &~ (SHF_MIPS_GPREL |
+   SHF_MIPS_MERGE |
+   SHF_MIPS_ADDR |
+   SHF_MIPS_STRINGS |
+   SHF_MIPS_NOSTRIP |
+   SHF_MIPS_LOCAL |
+   SHF_MIPS_NAMES |
+   SHF_MIPS_NODUPE)) == 0);
+}
+
 /* Check whether machine flags are valid.  */
 bool
 mips_machine_flag_check (GElf_Word flags)
diff --git a/src/elflint.c b/src/elflint.c
index 864de710..092409a2 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -936,7 +936,9 @@ section [%2d] '%s': symbol %zu (%s): non-local symbol 
outside range described in
}
 
   if (GELF_ST_TYPE (sym->st_info) == STT_SECTION
- && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && GELF_ST_BIND (sym->st_info) != STB_LOCAL
+ && ehdr->e_machine != EM_MIPS
+ && strcmp (name, "_DYNAMIC_LINKING") != 0)
ERROR (_("\
 section [%2d] '%s': symbol %zu (%s): non-local section symbol\n"),
   idx, section_name (ebl, idx), cnt, name);
@@ -3828,6 +3830,10 @@ cannot get section header for section [%2zu] '%s': 
%s\n"),
&& ebl_bss_plt_p (ebl))
  good_type = SHT_NOBITS;
 
+   if (ehdr->e_machine == EM_MIPS
+   && (strstr(special_sections[s].name, ".debug") != NULL))
+ good_type = SHT_MIPS_DWARF;
+
/* In a debuginfo file, any normal section can be SHT_NOBITS.
   This is only invalid for DWARF sections and .shstrtab.  */
if (shdr->sh_type != good_type
@@ -3988,12 +3994,21 @@ section [%2zu] '%s': size not multiple of entry 
size\n"),
ERROR (_("section [%2zu] '%s'"
" contains invalid processor-specific flag(s)"

[PATCH v3 5/6] stack: Fix stack unwind failure on mips

2024-03-05 Thread Ying Huang
From: Ying Huang 

Add abi_cfi, set_initial_registers_tid, unwind on mips.

Signed-off-by: Ying Huang 
---
 backends/Makefile.am|  3 +-
 backends/mips_cfi.c | 68 +
 backends/mips_init.c|  4 ++
 backends/mips_initreg.c | 61 ++
 backends/mips_unwind.c  | 84 +
 5 files changed, 219 insertions(+), 1 deletion(-)
 create mode 100644 backends/mips_cfi.c
 create mode 100644 backends/mips_initreg.c
 create mode 100644 backends/mips_unwind.c

diff --git a/backends/Makefile.am b/backends/Makefile.am
index ad95526e..5e7b7f21 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -102,7 +102,8 @@ loongarch_SRCS = loongarch_init.c loongarch_symbol.c 
loongarch_cfi.c \
 
 arc_SRCS = arc_init.c arc_symbol.c
 
-mips_SRCS = mips_init.c mips_symbol.c mips_attrs.c
+mips_SRCS = mips_init.c mips_symbol.c mips_attrs.c mips_initreg.c \
+   mips_cfi.c mips_unwind.c
 
 libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \
$(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \
diff --git a/backends/mips_cfi.c b/backends/mips_cfi.c
new file mode 100644
index ..60cf8111
--- /dev/null
+++ b/backends/mips_cfi.c
@@ -0,0 +1,68 @@
+/* MIPS ABI-specified defaults for DWARF CFI.
+   Copyright (C) 2009 Red Hat, Inc.
+   Copyright (C) 2024 CIP United Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * 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
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see .  */
+
+#ifdef HAVE_CONFIG_H
+# include 
+#endif
+
+#include 
+
+#define BACKEND mips_
+#include "libebl_CPU.h"
+
+int
+mips_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+{
+  DW_CFA_def_cfa, ULEB128_7 (31), ULEB128_7 (0),
+  /* Callee-saved regs.  */
+  DW_CFA_same_value, ULEB128_7 (16), /* s0 */
+  DW_CFA_same_value, ULEB128_7 (17), /* s1 */
+  DW_CFA_same_value, ULEB128_7 (18), /* s2 */
+  DW_CFA_same_value, ULEB128_7 (19), /* s3 */
+  DW_CFA_same_value, ULEB128_7 (20), /* s4 */
+  DW_CFA_same_value, ULEB128_7 (21), /* s5 */
+  DW_CFA_same_value, ULEB128_7 (22), /* s6 */
+  DW_CFA_same_value, ULEB128_7 (23), /* s7 */
+  DW_CFA_same_value, ULEB128_7 (28), /* gp */
+  DW_CFA_same_value, ULEB128_7 (29), /* sp */
+  DW_CFA_same_value, ULEB128_7 (30), /* fp */
+
+  DW_CFA_val_offset, ULEB128_7 (29), ULEB128_7 (0),
+};
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = 8;
+
+  abi_info->return_address_register = 31; /* %ra */
+
+  return 0;
+}
diff --git a/backends/mips_init.c b/backends/mips_init.c
index 521e6e51..1a2456b1 100644
--- a/backends/mips_init.c
+++ b/backends/mips_init.c
@@ -58,5 +58,9 @@ mips_init (Elf *elf __attribute__ ((unused)),
   HOOK (eh, check_object_attribute);
   HOOK (eh, check_special_symbol);
   HOOK (eh, check_reloc_target_type);
+  HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, abi_cfi);
+  HOOK (eh, unwind);
+  eh->frame_nregs = 71;
   return eh;
 }
diff --git a/backends/mips_initreg.c b/backends/mips_initreg.c
new file mode 100644
index ..21e7dedb
--- /dev/null
+++ b/backends/mips_initreg.c
@@ -0,0 +1,61 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2024 CIP United Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * 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
+
+   or both in parallel, as here.
+
+   elfutils 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 

[PATCH v3 6/6] backends: Add register_info, return_value_location, core_note function on mips

2024-03-05 Thread Ying Huang
From: Ying Huang 

Signed-off-by: Ying Huang 
---
 backends/Makefile.am |   3 +-
 backends/mips_corenote.c |  85 +
 backends/mips_init.c |   3 +
 backends/mips_regs.c | 135 +++
 backends/mips_retval.c   | 196 +++
 5 files changed, 421 insertions(+), 1 deletion(-)
 create mode 100644 backends/mips_corenote.c
 create mode 100644 backends/mips_regs.c
 create mode 100644 backends/mips_retval.c

diff --git a/backends/Makefile.am b/backends/Makefile.am
index 5e7b7f21..7c7f3351 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -103,7 +103,8 @@ loongarch_SRCS = loongarch_init.c loongarch_symbol.c 
loongarch_cfi.c \
 arc_SRCS = arc_init.c arc_symbol.c
 
 mips_SRCS = mips_init.c mips_symbol.c mips_attrs.c mips_initreg.c \
-   mips_cfi.c mips_unwind.c
+   mips_cfi.c mips_unwind.c mips_regs.c mips_retval.c \
+   mips_corenote.c
 
 libebl_backends_a_SOURCES = $(i386_SRCS) $(sh_SRCS) $(x86_64_SRCS) \
$(ia64_SRCS) $(alpha_SRCS) $(arm_SRCS) \
diff --git a/backends/mips_corenote.c b/backends/mips_corenote.c
new file mode 100644
index ..aeadeb17
--- /dev/null
+++ b/backends/mips_corenote.c
@@ -0,0 +1,85 @@
+/* MIPS specific core note handling.
+   Copyright (C) 2024 CIP United Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * 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
+
+   or both in parallel, as here.
+
+   elfutils 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 copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see .  */
+
+#ifdef HAVE_CONFIG_H
+# include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BACKENDmips_
+#include "libebl_CPU.h"
+
+#define BITS 64
+#ifndef BITS
+# define BITS  32
+#else
+# define BITS  64
+#endif
+
+#define PRSTATUS_REGS_SIZE (45 * (BITS / 8))
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+{ .offset = 0, .regno = 0, .count = (BITS == 32 ? 40 : 34), .bits = BITS },
+{ .offset = BITS/8 * (BITS == 32 ? 41 : 35), .regno = (BITS == 32 ? 41 : 
35), .count = (BITS == 32 ? 4 : 10), .bits = BITS },
+  };
+
+#define PRSTATUS_REGSET_ITEMS  \
+  {\
+.name = "pc", .type = ELF_T_ADDR, .format = 'x',   \
+.offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + ((BITS/8) * (BITS 
== 32 ? 40 : 34)),   \
+.group = "register",   \
+.pc_register = true
\
+  }
+
+#if BITS == 32
+# define ULONG uint32_t
+# define ALIGN_ULONG   4
+# define TYPE_ULONGELF_T_WORD
+#define TYPE_LONG  ELF_T_SWORD
+#else
+#define ULONG  uint64_t
+#define ALIGN_ULONG8
+#define TYPE_ULONG ELF_T_XWORD
+#define TYPE_LONG  ELF_T_SXWORD
+#endif
+#define PID_T  int32_t
+#defineUID_T   uint32_t
+#defineGID_T   uint32_t
+#define ALIGN_PID_T4
+#define ALIGN_UID_T4
+#define ALIGN_GID_T4
+#define TYPE_PID_T ELF_T_SWORD
+#define TYPE_UID_T ELF_T_WORD
+#define TYPE_GID_T ELF_T_WORD
+
+#include "linux-core-note.c"
diff --git a/backends/mips_init.c b/backends/mips_init.c
index 1a2456b1..711a934e 100644
--- a/backends/mips_init.c
+++ b/backends/mips_init.c
@@ -61,6 +61,9 @@ mips_init (Elf *elf __attribute__ ((unused)),
   HOOK (eh, set_initial_registers_tid);
   HOOK (eh, abi_cfi);
   HOOK (eh, unwind);
+  HOOK (eh, register_info);
+  HOOK (eh, return_value_location);
+  HOOK (eh, core_note);
   eh->frame_nregs = 71;
   return eh;
 }
diff --git a/backends/mips_regs.c b/backends/mips_regs.c
new file mode 100644
index ..4a1f8c50
--- /dev/null
+++ b/backends/mips_regs.c
@@ -0,0 +1,135 @@
+/* Register names and numbers for mips DWARF.
+   Copyright (C) 2006 Red Hat, Inc.
+   Copyright (C) 2024 CIP United Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it u