public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] Add support for MIPS
@ 2023-11-02  6:55 Ying Huang
  2023-11-02  6:55 ` [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips Ying Huang
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Ying Huang @ 2023-11-02  6:55 UTC (permalink / raw)
  To: elfutils-devel; +Cc: yunqiang.su

This is a series of modifications about MIPS.
Support src/readelf, strip, elflint, objdump related tools.

Pass all previous test cases that failed due to MIPS non-support.
The following are the test results on mips64el.
# TOTAL: 271
# PASS:  263
# SKIP:  8
# XFAIL: 0
# FAIL:  0
# XPASS: 0
# ERROR: 0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips
  2023-11-02  6:55 [PATCH v2 0/5] Add support for MIPS Ying Huang
@ 2023-11-02  6:55 ` Ying Huang
  2023-11-03 12:18   ` Mark Wielaard
  2023-11-02  6:55 ` [PATCH v2 2/5] readelf: Adapt src/readelf -h/-S/-r/-w/-l/-d/-a " Ying Huang
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Ying Huang @ 2023-11-02  6:55 UTC (permalink / raw)
  To: elfutils-devel; +Cc: yunqiang.su, Ying Huang

From: Ying Huang <ying.huang@oss.cipunited.com>

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.
---
 backends/Makefile.am    |   6 +-
 backends/mips_init.c    |  52 ++++++++++++++++
 backends/mips_reloc.def |  93 ++++++++++++++++++++++++++++
 backends/mips_symbol.c  |  63 +++++++++++++++++++
 libebl/eblopenbackend.c |   2 +
 libelf/elf_getdata.c    | 132 +++++++++++++++++++++++++++++++++++++++-
 libelf/elf_update.c     |  53 ++++++++++++++++
 libelf/libelfP.h        |   3 +
 8 files changed, 400 insertions(+), 4 deletions(-)
 create mode 100644 backends/mips_init.c
 create mode 100644 backends/mips_reloc.def
 create mode 100644 backends/mips_symbol.c

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 00000000..e26da609
--- /dev/null
+++ b/backends/mips_init.c
@@ -0,0 +1,52 @@
+/* Initialization of MIPS specific backend library.
+   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		mips_
+#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 00000000..8cb66a54
--- /dev/null
+++ b/backends/mips_reloc.def
@@ -0,0 +1,93 @@
+/* List the relocation types for MIPS.  -*- C -*-
+   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+
+RELOC_TYPE (NONE,		REL|EXEC|DYN)
+RELOC_TYPE (16,		        REL|EXEC|DYN)
+RELOC_TYPE (32,	                REL)
+RELOC_TYPE (REL32,	        REL|EXEC|DYN)
+RELOC_TYPE (26,		        REL|DYN)
+RELOC_TYPE (HI16,	        REL)
+RELOC_TYPE (LO16,		REL|EXEC|DYN)
+RELOC_TYPE (GPREL16,		REL|EXEC|DYN)
+RELOC_TYPE (LITERAL,		REL|EXEC|DYN)
+RELOC_TYPE (GOT16,		REL|EXEC|DYN)
+RELOC_TYPE (PC16,		REL)
+RELOC_TYPE (CALL16,		REL)
+RELOC_TYPE (GPREL32,		REL)
+RELOC_TYPE (SHIFT5,		REL)
+RELOC_TYPE (SHIFT6,		REL)
+RELOC_TYPE (64,		        REL)
+RELOC_TYPE (GOT_DISP,		REL)
+RELOC_TYPE (GOT_PAGE,		REL)
+RELOC_TYPE (GOT_OFST,		REL)
+RELOC_TYPE (GOT_HI16,		REL)
+RELOC_TYPE (GOT_LO16,		REL)
+RELOC_TYPE (SUB,		REL)
+RELOC_TYPE (INSERT_A,		REL)
+RELOC_TYPE (INSERT_B,		REL)
+RELOC_TYPE (DELETE,		REL)
+RELOC_TYPE (HIGHER,		REL)
+RELOC_TYPE (HIGHEST,		REL)
+RELOC_TYPE (CALL_HI16,		REL)
+RELOC_TYPE (CALL_LO16,		REL)
+RELOC_TYPE (SCN_DISP,		REL)
+RELOC_TYPE (REL16,		REL)
+RELOC_TYPE (ADD_IMMEDIATE,	REL)
+RELOC_TYPE (PJUMP,		REL)
+RELOC_TYPE (RELGOT,		REL)
+RELOC_TYPE (JALR,		REL)
+RELOC_TYPE (TLS_DTPMOD32,	DYN)
+RELOC_TYPE (TLS_DTPREL32,	REL)
+RELOC_TYPE (TLS_DTPMOD64,	DYN)
+RELOC_TYPE (TLS_DTPREL64,	REL)
+RELOC_TYPE (TLS_GD,		REL)
+RELOC_TYPE (TLS_LDM,		REL)
+RELOC_TYPE (TLS_DTPREL_HI16,	REL)
+RELOC_TYPE (TLS_DTPREL_LO16,	REL)
+RELOC_TYPE (TLS_GOTTPREL,	REL)
+RELOC_TYPE (TLS_TPREL32,	REL)
+RELOC_TYPE (TLS_TPREL64,	REL)
+RELOC_TYPE (TLS_TPREL_HI16,	REL)
+RELOC_TYPE (TLS_TPREL_LO16,	REL)
+RELOC_TYPE (GLOB_DAT,		REL)
+RELOC_TYPE (PC21_S2,		REL)
+RELOC_TYPE (PC26_S2,		REL)
+RELOC_TYPE (PC18_S3,		REL)
+RELOC_TYPE (PC19_S2,		REL)
+RELOC_TYPE (PCHI16,		REL)
+RELOC_TYPE (PCLO16,		REL)
+RELOC_TYPE (COPY,		REL)
+RELOC_TYPE (JUMP_SLOT,		REL)
+RELOC_TYPE (PC32,		REL)
+RELOC_TYPE (EH,			REL)
+RELOC_TYPE (GNU_REL16_S2,	REL)
+RELOC_TYPE (GNU_VTINHERIT,	REL)
+RELOC_TYPE (GNU_VTENTRY,	REL)
diff --git a/backends/mips_symbol.c b/backends/mips_symbol.c
new file mode 100644
index 00000000..a9dd5c09
--- /dev/null
+++ b/backends/mips_symbol.c
@@ -0,0 +1,63 @@
+/* MIPS specific symbolic name handling.
+   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <system.h>
+
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#define BACKEND		mips_
+#include "libebl_CPU.h"
+#include "libelfP.h"
+
+/* Check for the simple reloc types.  */
+Elf_Type
+mips_reloc_simple_type (Ebl *ebl, int type,
+			   int *addsub __attribute__ ((unused)))
+{
+  int typeNew = type;
+  if(ebl->elf->class == ELFCLASS64)
+    typeNew = ELF64_MIPS_R_TYPE1(type);
+  switch (typeNew)
+    {
+    case R_MIPS_64:
+      return ELF_T_XWORD;
+    case R_MIPS_32:
+      return ELF_T_WORD;
+    case R_MIPS_16:
+      return ELF_T_HALF;
+
+    default:
+      return ELF_T_NUM;
+    }
+}
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
index 084a1544..a5f7467a 100644
--- a/libebl/eblopenbackend.c
+++ b/libebl/eblopenbackend.c
@@ -57,6 +57,7 @@ Ebl *riscv_init (Elf *, GElf_Half, Ebl *);
 Ebl *csky_init (Elf *, GElf_Half, Ebl *);
 Ebl *loongarch_init (Elf *, GElf_Half, Ebl *);
 Ebl *arc_init (Elf *, GElf_Half, Ebl *);
+Ebl *mips_init (Elf *, GElf_Half, Ebl *);
 
 /* This table should contain the complete list of architectures as far
    as the ELF specification is concerned.  */
@@ -154,6 +155,7 @@ static const struct
   { csky_init, "elf_csky", "csky", 4, EM_CSKY, ELFCLASS32, ELFDATA2LSB },
   { loongarch_init, "elf_loongarch", "loongarch", 9, EM_LOONGARCH, ELFCLASS64, ELFDATA2LSB },
   { arc_init, "elf_arc", "arc", 3, EM_ARCV2, ELFCLASS32, ELFDATA2LSB },
+  { mips_init, "elf_mips", "mips", 4, EM_MIPS, 0, 0 },
 };
 #define nmachines (sizeof (machines) / sizeof (machines[0]))
 
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 & 0xffffffff) << 32)
+			| ((info >> 56) & 0xff)
+			| ((info >> 40) & 0xff00)
+			| ((info >> 24) & 0xff0000)
+			| ((info >> 8) & 0xff000000));
+	  ((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 = 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_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
+	    Elf64_Xword info = value->r_info;
+	    value->r_info = (((info & 0xffffffff) << 32)
+			| ((info >> 56) & 0xff)
+			| ((info >> 40) & 0xff00)
+			| ((info >> 24) & 0xff0000)
+			| ((info >> 8) & 0xff000000));
+	    ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
+	  }
+      }
+}
+
 /* Convert the data in the current section.  */
 static void
 convert_data (Elf_Scn *scn, int eclass,
@@ -451,8 +564,23 @@ __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
 	    return;
 	}
 
-      /* Convert according to the version and the type.   */
-      convert_data (scn, elf->class,
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      GElf_Ehdr ehdr_mem;
+      GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
+      if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
+	  scn->elf->class == ELFCLASS64 && ehdr != NULL &&
+	  ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
+	convert_data_for_mips64el (scn, elf->class,
+		    (elf->class == ELFCLASS32
+		     || (offsetof (struct Elf, state.elf32.ehdr)
+			 == offsetof (struct Elf, state.elf64.ehdr))
+		     ? elf->state.elf32.ehdr->e_ident[EI_DATA]
+		     : elf->state.elf64.ehdr->e_ident[EI_DATA]),
+		    scn->rawdata.d.d_size, scn->rawdata.d.d_type);
+      else
+	/* Convert according to the version and the type.   */
+	convert_data (scn, elf->class,
 		    (elf->class == ELFCLASS32
 		     || (offsetof (struct Elf, state.elf32.ehdr)
 			 == offsetof (struct Elf, state.elf64.ehdr))
diff --git a/libelf/elf_update.c b/libelf/elf_update.c
index 56af3a1c..aec19b7c 100644
--- a/libelf/elf_update.c
+++ b/libelf/elf_update.c
@@ -228,7 +228,60 @@ elf_update (Elf *elf, Elf_Cmd cmd)
 	  size = -1;
 	}
       else
+	{
+	  /* 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. */
+	  Elf_Scn *scn = NULL;
+	  while ((scn = elf_nextscn (elf, scn)) != NULL)
+	    {
+	      GElf_Shdr shdr_mem;
+	      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	      GElf_Ehdr ehdr_mem;
+	      GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
+	      if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
+		scn->elf->class == ELFCLASS64 &&
+		ehdr != NULL && ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
+		{
+		  Elf_Data *d = elf_getdata (scn, NULL);
+		  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 *) d;
+			  Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
+			  Elf64_Xword info = value->r_info;
+			  value->r_info = (info >> 32
+					| ((info << 56) & 0xff00000000000000)
+					| ((info << 40) & 0xff000000000000)
+					| ((info << 24) & 0xff0000000000)
+					| ((info << 8) & 0xff00000000));
+			  ((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 = shdr->sh_size / sh_entsize;
+		      for (int cnt = 0; cnt < nentries; cnt++)
+			{
+			  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) d;
+			  Elf64_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
+			  Elf64_Xword info = value->r_info;
+			  value->r_info = (info >> 32
+					| ((info << 56) & 0xff00000000000000)
+					| ((info << 40) & 0xff000000000000)
+					| ((info << 24) & 0xff0000000000)
+					| ((info << 8) & 0xff00000000));
+			  ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
+			}
+		    }
+		}
+	    }
 	size = write_file (elf, size, change_bo, shnum);
+      }
     }
 
  out:
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index ed061abb..bdd2cc6a 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -617,4 +617,7 @@ extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size,
 #define INVALID_NDX(ndx, type, data) \
   unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx))
 
+#define ELF64_MIPS_R_TYPE1(i)          ((i) & 0xff)
+#define ELF64_MIPS_R_TYPE2(i)           (((i) >> 8) & 0xff)
+#define ELF64_MIPS_R_TYPE3(i)           (((i) >> 16) & 0xff)
 #endif  /* libelfP.h */
-- 
2.30.2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 2/5] readelf: Adapt src/readelf -h/-S/-r/-w/-l/-d/-a on mips
  2023-11-02  6:55 [PATCH v2 0/5] Add support for MIPS Ying Huang
  2023-11-02  6:55 ` [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips Ying Huang
@ 2023-11-02  6:55 ` Ying Huang
  2023-11-02  6:56 ` [PATCH v2 3/5] elflint: adapt src/elflint --gnu src/nm " Ying Huang
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 17+ messages in thread
From: Ying Huang @ 2023-11-02  6:55 UTC (permalink / raw)
  To: elfutils-devel; +Cc: yunqiang.su, Ying Huang

From: Ying Huang <ying.huang@oss.cipunited.com>

-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.
---
 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          |   4 +-
 tests/run-readelf-reloc.sh |  42 +++
 8 files changed, 906 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 00000000..950047c3
--- /dev/null
+++ b/backends/mips_attrs.c
@@ -0,0 +1,140 @@
+/* Object attribute tags for MIPS.
+   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#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_MIPS_ABI_FP_XX:
+	    *value_name = "Hard float (32-bit CPU, Any FPU)";
+	    return true;
+	  case Val_GNU_MIPS_ABI_FP_64:
+	    *value_name = "Hard float (32-bit CPU, 64-bit FPU)";
+	    return true;
+	  case Val_GNU_MIPS_ABI_FP_64A:
+	    *value_name = "Hard float compat (32-bit CPU, 64-bit FPU)";
+	    return true;
+	  case Val_GNU_MIPS_ABI_FP_NAN2008:
+	    *value_name = "NaN 2008 compatibility";
+	    return true;
+	  default:
+	    return true;
+	}
+	return true;
+      case Tag_GNU_MIPS_ABI_MSA:
+	*tag_name = "Tag_GNU_MIPS_ABI_MSA";
+	switch (value)
+	{
+	  case Val_GNU_MIPS_ABI_MSA_ANY:
+	    *value_name = "Any MSA or not";
+	    return true;
+	  case Val_GNU_MIPS_ABI_MSA_128:
+	    *value_name = "128-bit MSA";
+	    return true;
+	  default:
+	    return true;
+	}
+	return true;
+      }
+
+  return false;
+}
diff --git a/backends/mips_init.c b/backends/mips_init.c
index e26da609..905d97eb 100644
--- a/backends/mips_init.c
+++ b/backends/mips_init.c
@@ -48,5 +48,12 @@ mips_init (Elf *elf __attribute__ ((unused)),
   /* We handle it.  */
   mips_init_reloc (eh);
   HOOK (eh, reloc_simple_type);
+  HOOK (eh, section_type_name);
+  HOOK (eh, machine_flag_check);
+  HOOK (eh, machine_flag_name);
+  HOOK (eh, segment_type_name);
+  HOOK (eh, dynamic_tag_check);
+  HOOK (eh, dynamic_tag_name);
+  HOOK (eh, check_object_attribute);
   return eh;
 }
diff --git a/backends/mips_symbol.c b/backends/mips_symbol.c
index a9dd5c09..6418a01d 100644
--- a/backends/mips_symbol.c
+++ b/backends/mips_symbol.c
@@ -61,3 +61,574 @@ mips_reloc_simple_type (Ebl *ebl, int type,
       return ELF_T_NUM;
     }
 }
+
+/* copy binutils-2.34/binutils/readelf.c get_mips_section_type_name  */
+const char *
+mips_section_type_name (int type,
+		       char *buf __attribute__ ((unused)),
+		       size_t len __attribute__ ((unused)))
+{
+  switch (type)
+    {
+    case SHT_MIPS_LIBLIST:
+      return "MIPS_LIBLIST";
+    case SHT_MIPS_MSYM:
+      return "MIPS_MSYM";
+    case SHT_MIPS_CONFLICT:
+      return "MIPS_CONFLICT";
+    case SHT_MIPS_GPTAB:
+      return "MIPS_GPTAB";
+    case SHT_MIPS_UCODE:
+      return "MIPS_UCODE";
+    case SHT_MIPS_DEBUG:
+      return "MIPS_DEBUG";
+    case SHT_MIPS_REGINFO:
+      return "MIPS_REGINFO";
+    case SHT_MIPS_PACKAGE:
+      return "MIPS_PACKAGE";
+    case SHT_MIPS_PACKSYM:
+      return "MIPS_PACKSYM";
+    case SHT_MIPS_RELD:
+      return "MIPS_RELD";
+    case SHT_MIPS_IFACE:
+      return "MIPS_IFACE";
+    case SHT_MIPS_CONTENT:
+      return "MIPS_CONTENT";
+    case SHT_MIPS_OPTIONS:
+      return "MIPS_OPTIONS";
+    case SHT_MIPS_SHDR:
+      return "MIPS_SHDR";
+    case SHT_MIPS_FDESC:
+      return "MIPS_FDESC";
+    case SHT_MIPS_EXTSYM:
+      return "MIPS_EXTSYM";
+    case SHT_MIPS_DENSE:
+      return "MIPS_DENSE";
+    case SHT_MIPS_PDESC:
+      return "MIPS_PDESC";
+    case SHT_MIPS_LOCSYM:
+      return "MIPS_LOCSYM";
+    case SHT_MIPS_AUXSYM:
+      return "MIPS_AUXSYM";
+    case SHT_MIPS_OPTSYM:
+      return "MIPS_OPTSYM";
+    case SHT_MIPS_LOCSTR:
+      return "MIPS_LOCSTR";
+    case SHT_MIPS_LINE:
+      return "MIPS_LINE";
+    case SHT_MIPS_RFDESC:
+      return "MIPS_RFDESC";
+    case SHT_MIPS_DELTASYM:
+      return "MIPS_DELTASYM";
+    case SHT_MIPS_DELTAINST:
+      return "MIPS_DELTAINST";
+    case SHT_MIPS_DELTACLASS:
+      return "MIPS_DELTACLASS";
+    case SHT_MIPS_DWARF:
+      return "MIPS_DWARF";
+    case SHT_MIPS_DELTADECL:
+      return "MIPS_DELTADECL";
+    case SHT_MIPS_SYMBOL_LIB:
+      return "MIPS_SYMBOL_LIB";
+    case SHT_MIPS_EVENTS:
+      return "MIPS_EVENTS";
+    case SHT_MIPS_TRANSLATE:
+      return "MIPS_TRANSLATE";
+    case SHT_MIPS_PIXIE:
+      return "MIPS_PIXIE";
+    case SHT_MIPS_XLATE:
+      return "MIPS_XLATE";
+    case SHT_MIPS_XLATE_DEBUG:
+      return "MIPS_XLATE_DEBUG";
+    case SHT_MIPS_WHIRL:
+      return "MIPS_WHIRL";
+    case SHT_MIPS_EH_REGION:
+      return "MIPS_EH_REGION";
+    case SHT_MIPS_XLATE_OLD:
+      return "MIPS_XLATE_OLD";
+    case SHT_MIPS_PDR_EXCEPTION:
+      return "MIPS_PDR_EXCEPTION";
+    case SHT_MIPS_ABIFLAGS:
+      return "MIPS_ABIFLAGS";
+    case SHT_MIPS_XHASH:
+      return "MIPS_XHASH";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+/* Check whether machine flags are valid.  */
+bool
+mips_machine_flag_check (GElf_Word flags)
+{
+  if ((flags &~ (EF_MIPS_NOREORDER |
+		 EF_MIPS_PIC |
+		 EF_MIPS_CPIC |
+		 EF_MIPS_UCODE |
+		 EF_MIPS_ABI2 |
+		 EF_MIPS_OPTIONS_FIRST |
+		 EF_MIPS_32BITMODE |
+		 EF_MIPS_NAN2008 |
+		 EF_MIPS_FP64 |
+		 EF_MIPS_ARCH_ASE_MDMX |
+		 EF_MIPS_ARCH_ASE_M16 |
+		 EF_MIPS_ARCH_ASE_MICROMIPS)) == 0)
+    return false;
+
+  switch(flags & EF_MIPS_MACH)
+    {
+    case EF_MIPS_MACH_3900:
+    case EF_MIPS_MACH_4010:
+    case EF_MIPS_MACH_4100:
+    case EF_MIPS_MACH_4111:
+    case EF_MIPS_MACH_4120:
+    case EF_MIPS_MACH_4650:
+    case EF_MIPS_MACH_5400:
+    case EF_MIPS_MACH_5500:
+    case EF_MIPS_MACH_5900:
+    case EF_MIPS_MACH_SB1:
+    case EF_MIPS_MACH_9000:
+    case EF_MIPS_MACH_LS2E:
+    case EF_MIPS_MACH_LS2F:
+    case EF_MIPS_MACH_GS464:
+    case EF_MIPS_MACH_GS464E:
+    case EF_MIPS_MACH_GS264E:
+    case EF_MIPS_MACH_OCTEON:
+    case EF_MIPS_MACH_OCTEON2:
+    case EF_MIPS_MACH_OCTEON3:
+    case EF_MIPS_MACH_XLR:
+    case EF_MIPS_MACH_IAMR2:
+    case 0:
+      break;
+    default:
+      return false;
+    }
+
+  switch ((flags & EF_MIPS_ABI))
+    {
+    case EF_MIPS_ABI_O32:
+    case EF_MIPS_ABI_O64:
+    case EF_MIPS_ABI_EABI32:
+    case EF_MIPS_ABI_EABI64:
+    case 0:
+      break;
+    default:
+      return false;
+    }
+
+  switch ((flags & EF_MIPS_ARCH))
+    {
+    case EF_MIPS_ARCH_1:
+    case EF_MIPS_ARCH_2:
+    case EF_MIPS_ARCH_3:
+    case EF_MIPS_ARCH_4:
+    case EF_MIPS_ARCH_5:
+    case EF_MIPS_ARCH_32:
+    case EF_MIPS_ARCH_32R2:
+    case EF_MIPS_ARCH_32R6:
+    case EF_MIPS_ARCH_64:
+    case EF_MIPS_ARCH_64R2:
+    case EF_MIPS_ARCH_64R6:
+      return true;
+    default:
+      return false;
+    }
+  return false;
+}
+
+/* copy binutils-2.34/binutils/readelf.c get_machine_flags */
+const char *
+mips_machine_flag_name (Elf64_Word orig __attribute__ ((unused)), Elf64_Word *flagref)
+{
+  if (*flagref & EF_MIPS_NOREORDER)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_NOREORDER);
+      return "noreorder";
+    }
+
+  if (*flagref & EF_MIPS_PIC)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_PIC);
+      return "pic";
+    }
+
+  if (*flagref & EF_MIPS_CPIC)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_CPIC);
+      return "cpic";
+    }
+
+  if (*flagref & EF_MIPS_UCODE)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_UCODE);
+      return "ugen_reserved";
+    }
+
+  if (*flagref & EF_MIPS_ABI2)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_ABI2);
+      return "abi2";
+    }
+
+  if (*flagref & EF_MIPS_OPTIONS_FIRST)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_OPTIONS_FIRST);
+      return "odk first";
+    }
+
+  if (*flagref & EF_MIPS_32BITMODE)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_32BITMODE);
+      return "32bitmode";
+    }
+
+  if (*flagref & EF_MIPS_NAN2008)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_NAN2008);
+      return "nan2008";
+    }
+
+  if (*flagref & EF_MIPS_FP64)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_FP64);
+      return "fp64";
+    }
+
+  switch (*flagref & EF_MIPS_MACH)
+    {
+    case EF_MIPS_MACH_3900:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_3900);
+      return "3900";
+    case EF_MIPS_MACH_4010:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4010);
+      return "4010";
+    case EF_MIPS_MACH_4100:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4100);
+      return "4100";
+    case EF_MIPS_MACH_4111:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4111);
+      return "4111";
+    case EF_MIPS_MACH_4120:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4120);
+      return "4120";
+    case EF_MIPS_MACH_4650:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_4650);
+      return "4650";
+    case EF_MIPS_MACH_5400:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_5400);
+      return "5400";
+    case EF_MIPS_MACH_5500:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_5500);
+      return "5500";
+    case EF_MIPS_MACH_5900:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_5900);
+      return "5900";
+    case EF_MIPS_MACH_SB1:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_SB1);
+      return "sb1";
+    case EF_MIPS_MACH_9000:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_9000);
+      return "9000";
+    case EF_MIPS_MACH_LS2E:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_LS2E);
+      return "loongson-2e";
+    case EF_MIPS_MACH_LS2F:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_LS2F);
+      return "loongson-2f";
+    case EF_MIPS_MACH_GS464:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_GS464);
+      return "gs464";
+    case EF_MIPS_MACH_GS464E:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_GS464E);
+      return "gs464e";
+    case EF_MIPS_MACH_GS264E:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_GS264E);
+      return "gs264e";
+    case EF_MIPS_MACH_OCTEON:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_OCTEON);
+      return "octeon";
+    case EF_MIPS_MACH_OCTEON2:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_OCTEON2);
+      return "octeon2";
+    case EF_MIPS_MACH_OCTEON3:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_OCTEON3);
+      return "octeon3";
+    case EF_MIPS_MACH_XLR:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_XLR);
+      return "xlr";
+    case EF_MIPS_MACH_IAMR2:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH_IAMR2);
+      return "interaptiv-mr2";
+    case 0:
+      /* We simply ignore the field in this case to avoid confusion:
+	 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
+	 extension.  */
+      break;
+    default:
+      *flagref &= ~((Elf64_Word) EF_MIPS_MACH);
+      return "unknown CPU";
+    }
+  switch (*flagref & EF_MIPS_ABI)
+    {
+    case EF_MIPS_ABI_O32:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ABI_O32);
+      return "o32";
+    case EF_MIPS_ABI_O64:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ABI_O64);
+      return "o64";
+    case EF_MIPS_ABI_EABI32:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ABI_EABI32);
+      return "eabi32";
+    case EF_MIPS_ABI_EABI64:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ABI_EABI64);
+      return "eabi64";
+    case 0:
+      /* We simply ignore the field in this case to avoid confusion:
+	 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
+	 This means it is likely to be an o32 file, but not for
+	 sure.  */
+      break;
+    default:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ABI);
+      return "unknown ABI";
+    }
+
+  if (*flagref & EF_MIPS_ARCH_ASE_MDMX)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_ASE_MDMX);
+      return "mdmx";
+    }
+
+  if (*flagref & EF_MIPS_ARCH_ASE_M16)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_ASE_M16);
+      return "mips16";
+    }
+
+  if (*flagref & EF_MIPS_ARCH_ASE_MICROMIPS)
+    {
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_ASE_MICROMIPS);
+      return "micromips";
+    }
+
+  switch (*flagref & EF_MIPS_ARCH)
+    {
+    case EF_MIPS_ARCH_1:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_1);
+      return "mips1";
+    case EF_MIPS_ARCH_2:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_2);
+      return "mips2";
+    case EF_MIPS_ARCH_3:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_3);
+      return "mips3";
+    case EF_MIPS_ARCH_4:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_4);
+      return "mips4";
+    case EF_MIPS_ARCH_5:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_5);
+      return "mips5";
+    case EF_MIPS_ARCH_32:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32);
+      return "mips32";
+    case EF_MIPS_ARCH_32R2:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32R2);
+      return "mips32r2";
+    case EF_MIPS_ARCH_32R6:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_32R6);
+      return "mips32r6";
+    case EF_MIPS_ARCH_64:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_64);
+      return "mips64";
+    case EF_MIPS_ARCH_64R2:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_64R2);
+      return "mips64r2";
+    case EF_MIPS_ARCH_64R6:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH_64R6);
+      return "mips64r6";
+    default:
+      *flagref &= ~((Elf64_Word) EF_MIPS_ARCH);
+      return "unknown ISA";
+    }
+  return NULL;
+}
+
+/* copy binutils-2.34/binutils/readelf.c get_mips_segment_type  */
+const char *
+mips_segment_type_name (int segment, char *buf __attribute__ ((unused)),
+			size_t len __attribute__ ((unused)))
+{
+  switch (segment)
+    {
+    case PT_MIPS_REGINFO:
+      return "REGINFO";
+    case PT_MIPS_RTPROC:
+      return "RTPROC";
+    case PT_MIPS_OPTIONS:
+      return "OPTIONS";
+    case PT_MIPS_ABIFLAGS:
+      return "ABIFLAGS";
+    default:
+      return NULL;
+    }
+}
+
+bool
+mips_dynamic_tag_check (int64_t tag)
+{
+  return ((tag &~ (DT_MIPS_RLD_VERSION
+	  | DT_MIPS_TIME_STAMP
+	  | DT_MIPS_ICHECKSUM
+	  | DT_MIPS_IVERSION
+	  | DT_MIPS_FLAGS
+	  | DT_MIPS_BASE_ADDRESS
+	  | DT_MIPS_MSYM
+	  | DT_MIPS_CONFLICT
+	  | DT_MIPS_LIBLIST
+	  | DT_MIPS_LOCAL_GOTNO
+	  | DT_MIPS_CONFLICTNO
+	  | DT_MIPS_LIBLISTNO
+	  | DT_MIPS_SYMTABNO
+	  | DT_MIPS_UNREFEXTNO
+	  | DT_MIPS_GOTSYM
+	  | DT_MIPS_HIPAGENO
+	  | DT_MIPS_RLD_MAP
+	  | DT_MIPS_DELTA_CLASS
+	  | DT_MIPS_DELTA_CLASS_NO
+	  | DT_MIPS_DELTA_INSTANCE
+	  | DT_MIPS_DELTA_INSTANCE_NO
+	  | DT_MIPS_DELTA_RELOC
+	  | DT_MIPS_DELTA_RELOC_NO
+	  | DT_MIPS_DELTA_SYM
+	  | DT_MIPS_DELTA_SYM_NO
+	  | DT_MIPS_DELTA_CLASSSYM
+	  | DT_MIPS_DELTA_CLASSSYM_NO
+	  | DT_MIPS_CXX_FLAGS
+	  | DT_MIPS_PIXIE_INIT
+	  | DT_MIPS_SYMBOL_LIB
+	  | DT_MIPS_LOCALPAGE_GOTIDX
+	  | DT_MIPS_LOCAL_GOTIDX
+	  | DT_MIPS_HIDDEN_GOTIDX
+	  | DT_MIPS_PROTECTED_GOTIDX
+	  | DT_MIPS_OPTIONS
+	  | DT_MIPS_INTERFACE
+	  | DT_MIPS_DYNSTR_ALIGN
+	  | DT_MIPS_INTERFACE_SIZE
+	  | DT_MIPS_RLD_TEXT_RESOLVE_ADDR
+	  | DT_MIPS_PERF_SUFFIX
+	  | DT_MIPS_COMPACT_SIZE
+	  | DT_MIPS_GP_VALUE
+	  | DT_MIPS_AUX_DYNAMIC
+	  | DT_MIPS_PLTGOT
+	  | DT_MIPS_RWPLT
+	  | DT_MIPS_RLD_MAP_REL
+	  | DT_MIPS_XHASH)) == 0);
+}
+
+/* copy binutils-2.34/binutils/readelf.c  get_mips_dynamic_type*/
+const char *
+mips_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+			  size_t len __attribute__ ((unused)))
+{
+  switch (tag)
+    {
+    case DT_MIPS_RLD_VERSION:
+      return "MIPS_RLD_VERSION";
+    case DT_MIPS_TIME_STAMP:
+      return "MIPS_TIME_STAMP";
+    case DT_MIPS_ICHECKSUM:
+      return "MIPS_ICHECKSUM";
+    case DT_MIPS_IVERSION:
+      return "MIPS_IVERSION";
+    case DT_MIPS_FLAGS:
+      return "MIPS_FLAGS";
+    case DT_MIPS_BASE_ADDRESS:
+      return "MIPS_BASE_ADDRESS";
+    case DT_MIPS_MSYM:
+      return "MIPS_MSYM";
+    case DT_MIPS_CONFLICT:
+      return "MIPS_CONFLICT";
+    case DT_MIPS_LIBLIST:
+      return "MIPS_LIBLIST";
+    case DT_MIPS_LOCAL_GOTNO:
+      return "MIPS_LOCAL_GOTNO";
+    case DT_MIPS_CONFLICTNO:
+      return "MIPS_CONFLICTNO";
+    case DT_MIPS_LIBLISTNO:
+      return "MIPS_LIBLISTNO";
+    case DT_MIPS_SYMTABNO:
+      return "MIPS_SYMTABNO";
+    case DT_MIPS_UNREFEXTNO:
+      return "MIPS_UNREFEXTNO";
+    case DT_MIPS_GOTSYM:
+      return "MIPS_GOTSYM";
+    case DT_MIPS_HIPAGENO:
+      return "MIPS_HIPAGENO";
+    case DT_MIPS_RLD_MAP:
+      return "MIPS_RLD_MAP";
+    case DT_MIPS_RLD_MAP_REL:
+      return "MIPS_RLD_MAP_REL";
+    case DT_MIPS_DELTA_CLASS:
+      return "MIPS_DELTA_CLASS";
+    case DT_MIPS_DELTA_CLASS_NO:
+      return "MIPS_DELTA_CLASS_NO";
+    case DT_MIPS_DELTA_INSTANCE:
+      return "MIPS_DELTA_INSTANCE";
+    case DT_MIPS_DELTA_INSTANCE_NO:
+      return "MIPS_DELTA_INSTANCE_NO";
+    case DT_MIPS_DELTA_RELOC:
+      return "MIPS_DELTA_RELOC";
+    case DT_MIPS_DELTA_RELOC_NO:
+      return "MIPS_DELTA_RELOC_NO";
+    case DT_MIPS_DELTA_SYM:
+      return "MIPS_DELTA_SYM";
+    case DT_MIPS_DELTA_SYM_NO:
+      return "MIPS_DELTA_SYM_NO";
+    case DT_MIPS_DELTA_CLASSSYM:
+      return "MIPS_DELTA_CLASSSYM";
+    case DT_MIPS_DELTA_CLASSSYM_NO:
+      return "MIPS_DELTA_CLASSSYM_NO";
+    case DT_MIPS_CXX_FLAGS:
+      return "MIPS_CXX_FLAGS";
+    case DT_MIPS_PIXIE_INIT:
+      return "MIPS_PIXIE_INIT";
+    case DT_MIPS_SYMBOL_LIB:
+      return "MIPS_SYMBOL_LIB";
+    case DT_MIPS_LOCALPAGE_GOTIDX:
+      return "MIPS_LOCALPAGE_GOTIDX";
+    case DT_MIPS_LOCAL_GOTIDX:
+      return "MIPS_LOCAL_GOTIDX";
+    case DT_MIPS_HIDDEN_GOTIDX:
+      return "MIPS_HIDDEN_GOTIDX";
+    case DT_MIPS_PROTECTED_GOTIDX:
+      return "MIPS_PROTECTED_GOTIDX";
+    case DT_MIPS_OPTIONS:
+      return "MIPS_OPTIONS";
+    case DT_MIPS_INTERFACE:
+      return "MIPS_INTERFACE";
+    case DT_MIPS_DYNSTR_ALIGN:
+      return "MIPS_DYNSTR_ALIGN";
+    case DT_MIPS_INTERFACE_SIZE:
+      return "MIPS_INTERFACE_SIZE";
+    case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:
+      return "MIPS_RLD_TEXT_RESOLVE_ADDR";
+    case DT_MIPS_PERF_SUFFIX:
+      return "MIPS_PERF_SUFFIX";
+    case DT_MIPS_COMPACT_SIZE:
+      return "MIPS_COMPACT_SIZE";
+    case DT_MIPS_GP_VALUE:
+      return "MIPS_GP_VALUE";
+    case DT_MIPS_AUX_DYNAMIC:
+      return "MIPS_AUX_DYNAMIC";
+    case DT_MIPS_PLTGOT:
+      return "MIPS_PLTGOT";
+    case DT_MIPS_RWPLT:
+      return "MIPS_RWPLT";
+    case DT_MIPS_XHASH:
+      return "MIPS_XHASH";
+    default:
+      return NULL;
+    }
+  return NULL;
+}
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index bdd2cc6a..6565ee02 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -620,4 +620,5 @@ extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size,
 #define ELF64_MIPS_R_TYPE1(i)          ((i) & 0xff)
 #define ELF64_MIPS_R_TYPE2(i)           (((i) >> 8) & 0xff)
 #define ELF64_MIPS_R_TYPE3(i)           (((i) >> 16) & 0xff)
+#define is_debug_section_type(type) (type == SHT_PROGBITS || type == SHT_MIPS_DWARF)
 #endif  /* libelfP.h */
diff --git a/src/readelf.c b/src/readelf.c
index db31ad09..b1c459d1 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -2219,17 +2219,41 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
 			(long int) GELF_R_SYM (rel->r_info));
 	    }
 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
-	    printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
-		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
-		    likely (ebl_reloc_type_check (ebl,
-						  GELF_R_TYPE (rel->r_info)))
-		    /* Avoid the leading R_ which isn't carrying any
-		       information.  */
-		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
-					   buf, sizeof (buf)) + 2
-		    : _("<INVALID RELOC>"),
-		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
-		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+	    {
+	      unsigned long inf = rel->r_info;
+	      printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
+		      class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+		      likely (ebl_reloc_type_check (ebl,
+						    GELF_R_TYPE (rel->r_info)))
+		      /* Avoid the leading R_ which isn't carrying any
+			information.  */
+		      ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					     buf, sizeof (buf)) + 2
+		      : _("<INVALID RELOC>"),
+		      class == ELFCLASS32 ? 10 : 18, sym->st_value,
+		      elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+
+	      /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753  */
+	      if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
+		{
+		  unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
+		  unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
+		  const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
+		  const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
+		  printf("		      Type2: ");
+		  if (rtype2 == NULL)
+		    printf (_("unrecognized: %lx"), (unsigned long) type2 & 0xffffffff);
+		  else
+		    printf ("%s", rtype2);
+
+		  printf ("\n		      Type3: ");
+		  if (rtype3 == NULL)
+		    printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff);
+		  else
+		    printf ("%s", rtype3);
+		  printf("\n");
+		}
+	    }
 	  else
 	    {
 	      /* This is a relocation against a STT_SECTION symbol.  */
@@ -2253,16 +2277,40 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
 			(long int) (sym->st_shndx == SHN_XINDEX
 				    ? xndx : sym->st_shndx));
 	      else
-		printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
-			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
-			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
-			/* Avoid the leading R_ which isn't carrying any
-			   information.  */
-			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
-					       buf, sizeof (buf)) + 2
-			: _("<INVALID RELOC>"),
-			class == ELFCLASS32 ? 10 : 18, sym->st_value,
-			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+		{
+		  unsigned long inf = rel->r_info;
+		  printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
+			  class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			  ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			  /* Avoid the leading R_ which isn't carrying any
+			     information.  */
+			  ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+						 buf, sizeof (buf)) + 2
+			  : _("<INVALID RELOC>"),
+			  class == ELFCLASS32 ? 10 : 18, sym->st_value,
+			  elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+
+		  /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753  */
+		  if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
+		  {
+		    unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
+		    unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
+		    const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
+		    const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
+		    printf("		      Type2: ");
+		    if (rtype2 == NULL)
+		      printf (_("unrecognized: %lx"), (unsigned long) type2 & 0xffffffff);
+		    else
+		      printf ("%s", rtype2);
+
+		    printf ("\n		      Type3: ");
+		    if (rtype3 == NULL)
+		      printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff);
+		    else
+		      printf ("%s", rtype3);
+		    printf("\n");
+		  }
+		}
 	    }
 	}
     }
@@ -2410,19 +2458,43 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
 			(long int) GELF_R_SYM (rel->r_info));
 	    }
 	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
-	    printf ("\
+	    {
+	      unsigned long inf = rel->r_info;
+	      printf ("\
   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
-		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
-		    likely (ebl_reloc_type_check (ebl,
-						  GELF_R_TYPE (rel->r_info)))
-		    /* Avoid the leading R_ which isn't carrying any
-		       information.  */
-		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
-					   buf, sizeof (buf)) + 2
-		    : _("<INVALID RELOC>"),
-		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
-		    rel->r_addend,
-		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+		      class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+		      likely (ebl_reloc_type_check (ebl,
+						    GELF_R_TYPE (rel->r_info)))
+		      /* Avoid the leading R_ which isn't carrying any
+			 information.  */
+		      ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					     buf, sizeof (buf)) + 2
+		      : _("<INVALID RELOC>"),
+		      class == ELFCLASS32 ? 10 : 18, sym->st_value,
+		      rel->r_addend,
+		      elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+
+	      /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753  */
+	      if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
+		{
+		  unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
+		  unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
+		  const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
+		  const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
+		  printf("		      Type2: ");
+		  if (rtype2 == NULL)
+		    printf (_("unrecognized: %lx"), (unsigned long) type2 & 0xffffffff);
+		  else
+		    printf ("%s", rtype2);
+
+		  printf ("\n		      Type3: ");
+		  if (rtype3 == NULL)
+		    printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff);
+		  else
+		    printf ("%s", rtype3);
+		  printf("\n");
+		}
+	    }
 	  else
 	    {
 	      /* This is a relocation against a STT_SECTION symbol.  */
@@ -2446,18 +2518,42 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
 			(long int) (sym->st_shndx == SHN_XINDEX
 				    ? xndx : sym->st_shndx));
 	      else
-		printf ("\
+		{
+		  unsigned long inf = rel->r_info;
+		  printf ("\
   %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
-			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
-			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
-			/* Avoid the leading R_ which isn't carrying any
-			   information.  */
-			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
-					       buf, sizeof (buf)) + 2
-			: _("<INVALID RELOC>"),
-			class == ELFCLASS32 ? 10 : 18, sym->st_value,
-			rel->r_addend,
-			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+			  class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			  ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			  /* Avoid the leading R_ which isn't carrying any
+			     information.  */
+			  ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+						 buf, sizeof (buf)) + 2
+			  : _("<INVALID RELOC>"),
+			  class == ELFCLASS32 ? 10 : 18, sym->st_value,
+			  rel->r_addend,
+			  elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+
+		  /* copy binutils-2.34/binutils/readelf.c dump_relocations+1753  */
+		  if(ebl->elf->class == ELFCLASS64 && ebl->elf->state.elf64.ehdr->e_machine == EM_MIPS)
+		    {
+		      unsigned int type2 = ELF64_MIPS_R_TYPE2 (inf);
+		      unsigned int type3 = ELF64_MIPS_R_TYPE3 (inf);
+		      const char * rtype2 = ebl_reloc_type_name (ebl, type2, buf, sizeof (buf)) + 2;
+		      const char * rtype3 = ebl_reloc_type_name (ebl, type3, buf, sizeof (buf)) + 2;
+		      printf("		      Type2: ");
+		      if (rtype2 == NULL)
+			printf (_("unrecognized: %-7lx"), (unsigned long) type2 & 0xffffffff);
+		      else
+			printf ("%s", rtype2);
+
+		      printf ("\n		      Type3: ");
+		      if (rtype3 == NULL)
+			printf (_("unrecognized: %lx"), (unsigned long) type3 & 0xffffffff);
+		      else
+			printf ("%s", rtype3);
+		      printf("\n");
+		    }
+		}
 	    }
 	}
     }
@@ -11976,7 +12072,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
 	  GElf_Shdr shdr_mem;
 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
 
-	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
+	  if (shdr != NULL && is_debug_section_type(shdr->sh_type))
 	    {
 	      const char *name = elf_strptr (ebl->elf, shstrndx,
 					     shdr->sh_name);
@@ -12006,7 +12102,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
       GElf_Shdr shdr_mem;
       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
 
-      if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
+      if (shdr != NULL && is_debug_section_type(shdr->sh_type))
 	{
 	  static const struct
 	  {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d0ae7c6d..a44d18a0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -212,7 +212,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
 	$(asm_TESTS) run-disasm-bpf.sh run-low_high_pc-dw-form-indirect.sh \
 	run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \
 	run-readelf-dw-form-indirect.sh run-strip-largealign.sh \
-	run-readelf-Dd.sh
+	run-readelf-Dd.sh run-readelf-reloc.sh
 
 if !BIARCH
 export ELFUTILS_DISABLE_BIARCH = 1
@@ -631,7 +631,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
 	     run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \
 	     testfile_nvidia_linemap.bz2 \
 	     testfile-largealign.o.bz2 run-strip-largealign.sh \
-	     run-funcretval++11.sh
+	     run-funcretval++11.sh run-readelf-reloc.sh
 
 
 if USE_VALGRIND
diff --git a/tests/run-readelf-reloc.sh b/tests/run-readelf-reloc.sh
new file mode 100755
index 00000000..0a279f65
--- /dev/null
+++ b/tests/run-readelf-reloc.sh
@@ -0,0 +1,42 @@
+#! /bin/bash
+# Copyright (C) 2018 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# 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 a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+tempfiles test-readelf-h.txt test-readelf-reloc.txt
+testrun ${abs_top_builddir}/src/readelf -h ${abs_top_builddir}/src/strip.o > test-readelf-h.txt
+machine=`cat test-readelf-h.txt | grep Machine`
+class=`cat test-readelf-h.txt | grep Class`
+endian=`cat test-readelf-h.txt | grep Data`
+if [[ "$machine" == *MIPS* && "$class" == *ELF64 && "$endian" == *little* ]]; then
+testrun ${abs_top_builddir}/src/readelf -r ${abs_top_builddir}/src/strip.o | head -n 12 | tail -n 10 > test-readelf-reloc.txt
+
+testrun_compare cat test-readelf-reloc.txt  << EOF
+  Offset              Type            Value               Addend Name
+  0x0000000000000008  MIPS_GPREL16    000000000000000000      +0 .text
+		      Type2: MIPS_SUB
+		      Type3: MIPS_HI16
+  0x0000000000000010  MIPS_GPREL16    000000000000000000      +0 .text
+		      Type2: MIPS_SUB
+		      Type3: MIPS_LO16
+  0x0000000000000014  MIPS_CALL16     000000000000000000      +0 gelf_getehdr
+		      Type2: MIPS_NONE
+		      Type3: MIPS_NONE
+EOF
+fi
+
+exit 0
-- 
2.30.2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 3/5] elflint: adapt src/elflint --gnu src/nm on mips
  2023-11-02  6:55 [PATCH v2 0/5] Add support for MIPS Ying Huang
  2023-11-02  6:55 ` [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips Ying Huang
  2023-11-02  6:55 ` [PATCH v2 2/5] readelf: Adapt src/readelf -h/-S/-r/-w/-l/-d/-a " Ying Huang
@ 2023-11-02  6:56 ` Ying Huang
  2023-11-02  6:56 ` [PATCH v2 4/5] stack: Fix stack unwind failure " Ying Huang
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 17+ messages in thread
From: Ying Huang @ 2023-11-02  6:56 UTC (permalink / raw)
  To: elfutils-devel; +Cc: yunqiang.su, Ying Huang

From: Ying Huang <ying.huang@oss.cipunited.com>

The errors were:
$ src/elflint --gnu src/nm
section [ 2] '.MIPS.options' contains unknown flag(s) 0x8000000
section [ 7] '.dynsym': symbol 165 (_DYNAMIC_LINKING): non-local section symbol
section [24] '.got' contains invalid processor-specific flag(s) 0x10000000
section [25] '.sdata' contains invalid processor-specific flag(s) 0x10000000
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
---
 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 905d97eb..e883b7e4 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 6418a01d..1e3d55c4 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)"
 				" %#" PRIx64 "\n"),
-		       cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
+			cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
 	      sh_flags &= ~(GElf_Xword) SHF_MASKPROC;
 	    }
 	  if (sh_flags & SHF_MASKOS)
-	    if (gnuld)
-	      sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN;
+	    {
+	      if (gnuld)
+		sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN;
+	      if (!ebl_machine_section_flag_check (ebl,
+						   sh_flags & SHF_MASKOS))
+		ERROR (_("section [%2zu] '%s'"
+				" contains invalid os-specific flag(s)"
+				" %#" PRIx64 "\n"),
+			cnt, section_name (ebl, cnt), sh_flags & SHF_MASKOS);
+	      sh_flags &= ~(GElf_Xword) SHF_MASKOS;
+	    }
 	  if (sh_flags != 0)
 	    ERROR (_("section [%2zu] '%s' contains unknown flag(s)"
 			    " %#" PRIx64 "\n"),
@@ -4059,6 +4074,7 @@ section [%2zu] '%s': merge flag set but entry size is zero\n"),
 	  switch (shdr->sh_type)
 	    {
 	    case SHT_PROGBITS:
+	    case SHT_MIPS_DWARF:
 	      break;
 
 	    case SHT_NOBITS:
@@ -4716,7 +4732,7 @@ program header offset in ELF header and PHDR entry do not match"));
 	      if (shdr != NULL
 		  && ((is_debuginfo && shdr->sh_type == SHT_NOBITS)
 		      || (! is_debuginfo
-			  && (shdr->sh_type == SHT_PROGBITS
+			  && (is_debug_section_type(shdr->sh_type)
 			      || shdr->sh_type == SHT_X86_64_UNWIND)))
 		  && elf_strptr (ebl->elf, shstrndx, shdr->sh_name) != NULL
 		  && ! strcmp (".eh_frame_hdr",
-- 
2.30.2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 4/5] stack: Fix stack unwind failure on mips
  2023-11-02  6:55 [PATCH v2 0/5] Add support for MIPS Ying Huang
                   ` (2 preceding siblings ...)
  2023-11-02  6:56 ` [PATCH v2 3/5] elflint: adapt src/elflint --gnu src/nm " Ying Huang
@ 2023-11-02  6:56 ` Ying Huang
  2023-11-02  6:56 ` [PATCH v2 5/5] backends: Add register_info, return_value_location, core_note function " Ying Huang
  2023-11-03 11:56 ` [PATCH v2 0/5] Add support for MIPS Mark Wielaard
  5 siblings, 0 replies; 17+ messages in thread
From: Ying Huang @ 2023-11-02  6:56 UTC (permalink / raw)
  To: elfutils-devel; +Cc: yunqiang.su, Ying Huang

From: Ying Huang <ying.huang@oss.cipunited.com>

Add abi_cfi, set_initial_registers_tid, unwind on mips.
---
 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 00000000..64cee1a9
--- /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) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#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 e883b7e4..a6ed8a47 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 00000000..87c879f5
--- /dev/null
+++ b/backends/mips_initreg.c
@@ -0,0 +1,61 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#if (defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)) && defined(__linux__)
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#include <asm/ptrace.h>
+#endif
+
+#define BACKEND mips_
+#include "libebl_CPU.h"
+
+
+bool
+mips_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
+			  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+				  void *arg __attribute__ ((unused)))
+{
+#if (!defined(mips) && !defined(__mips) && !defined(__mips__) && !defined(MIPS) && !defined(__MIPS__)) || !defined(__linux__)
+  return false;
+#else /* __mips__ */
+/* For PTRACE_GETREGS */
+
+  struct pt_regs gregs;
+  if (ptrace (PTRACE_GETREGS, tid, 0, &gregs) != 0)
+    return false;
+  if (! setfunc (-1, 1, (Dwarf_Word *) &gregs.cp0_epc, arg))
+    return false;
+  return setfunc (0, 32, (Dwarf_Word *) &gregs.regs[0], arg);
+#endif /* __mips__ */
+}
diff --git a/backends/mips_unwind.c b/backends/mips_unwind.c
new file mode 100644
index 00000000..4168d4ef
--- /dev/null
+++ b/backends/mips_unwind.c
@@ -0,0 +1,84 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2016 The Qt Company Ltd.
+   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND mips_
+#define SP_REG 29
+#define FP_REG 30
+#define LR_REG 31
+#define FP_OFFSET 0
+#define LR_OFFSET 8
+#define SP_OFFSET 16
+
+#include "libebl_CPU.h"
+
+/* There was no CFI. Maybe we happen to have a frame pointer and can unwind from that?  */
+
+bool
+EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr pc __attribute__ ((unused)),
+		 ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc,
+		 ebl_pid_memory_read_t *readfunc, void *arg,
+		 bool *signal_framep __attribute__ ((unused)))
+{
+  Dwarf_Word fp, lr, sp;
+
+  if (!getfunc(LR_REG, 1, &lr, arg))
+    return false;
+
+  if (lr == 0 || !setfunc(-1, 1, &lr, arg))
+    return false;
+
+  if (!getfunc(FP_REG, 1, &fp, arg))
+    fp = 0;
+
+  if (!getfunc(SP_REG, 1, &sp, arg))
+    sp = 0;
+
+  Dwarf_Word newLr, newFp, newSp;
+
+  if (!readfunc(fp + LR_OFFSET, &newLr, arg))
+    newLr = 0;
+
+  if (!readfunc(fp + FP_OFFSET, &newFp, arg))
+    newFp = 0;
+
+  newSp = fp + SP_OFFSET;
+
+  // These are not fatal if they don't work. They will just prevent unwinding at the next frame.
+  setfunc(LR_REG, 1, &newLr, arg);
+  setfunc(FP_REG, 1, &newFp, arg);
+  setfunc(SP_REG, 1, &newSp, arg);
+
+  // If the fp is invalid, we might still have a valid lr.
+  // But if the fp is valid, then the stack should be moving in the right direction.
+  return fp == 0 || newSp > sp;
+}
-- 
2.30.2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 5/5] backends: Add register_info, return_value_location, core_note function on mips
  2023-11-02  6:55 [PATCH v2 0/5] Add support for MIPS Ying Huang
                   ` (3 preceding siblings ...)
  2023-11-02  6:56 ` [PATCH v2 4/5] stack: Fix stack unwind failure " Ying Huang
@ 2023-11-02  6:56 ` Ying Huang
  2023-11-03 11:56 ` [PATCH v2 0/5] Add support for MIPS Mark Wielaard
  5 siblings, 0 replies; 17+ messages in thread
From: Ying Huang @ 2023-11-02  6:56 UTC (permalink / raw)
  To: elfutils-devel; +Cc: yunqiang.su, Ying Huang

From: Ying Huang <ying.huang@oss.cipunited.com>

---
 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 00000000..44e30e3e
--- /dev/null
+++ b/backends/mips_corenote.c
@@ -0,0 +1,85 @@
+/* MIPS specific core note handling.
+   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND	mips_
+#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_ULONG		ELF_T_WORD
+#define TYPE_LONG		ELF_T_SWORD
+#else
+#define ULONG			uint64_t
+#define ALIGN_ULONG		8
+#define TYPE_ULONG		ELF_T_XWORD
+#define TYPE_LONG		ELF_T_SXWORD
+#endif
+#define PID_T			int32_t
+#define	UID_T			uint32_t
+#define	GID_T			uint32_t
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		4
+#define ALIGN_GID_T		4
+#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 a6ed8a47..e5617f0f 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 00000000..28fe7cae
--- /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) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <string.h>
+
+#define BACKEND mips_
+#include "libebl_CPU.h"
+#include <system.h>
+ssize_t
+mips_register_info (Ebl *ebl __attribute__ ((unused)),
+		      int regno, char *name, size_t namelen,
+		      const char **prefix, const char **setname,
+		      int *bits, int *type)
+{
+  if (name == NULL)
+    return 72;
+
+  if (regno < 0 || regno > 71 || namelen < 4)
+    return -1;
+
+  *prefix = "$";
+  if (regno < 38)
+    {
+      *setname = "integer";
+      *type = DW_ATE_signed;
+      *bits = 32;
+    }
+  else
+    {
+      *setname = "FPU";
+      *type = DW_ATE_float;
+      *bits = 64;
+    }
+
+  if (regno < 32)
+    {
+      if (regno < 10)
+	{
+	  name[0] = regno + '0';
+	  namelen = 1;
+	}
+      else
+	{
+	  name[0] = (regno / 10) + '0';
+	  name[1] = (regno % 10) + '0';
+	  namelen = 2;
+	}
+      if (regno == 28 || regno == 29 || regno == 31)
+	*type = DW_ATE_address;
+    }
+  else if (regno == 32)
+    {
+      return stpcpy (name, "lo") + 1 - name;
+    }
+  else if (regno == 33)
+    {
+      return stpcpy (name, "hi") + 1 - name;
+    }
+  else if (regno == 34)
+    {
+      return stpcpy (name, "pc") + 1 - name;
+    }
+  else if (regno == 35)
+    {
+      *type = DW_ATE_address;
+      return stpcpy (name, "bad") + 1 - name;
+    }
+  else if (regno == 36)
+    {
+      return stpcpy (name, "sr") + 1 - name;
+    }
+  else if (regno == 37)
+    {
+      *type = DW_ATE_address;
+      return stpcpy (name, "cause") + 1 - name;
+    }
+  else if (regno < 70)
+    {
+      name[0] = 'f';
+      if (regno < 38 + 10)
+      {
+	name[1] = (regno - 38) + '0';
+	namelen = 2;
+      }
+      else
+      {
+	name[1] = (regno - 38) / 10 + '0';
+	name[2] = (regno - 38) % 10 + '0';
+	namelen = 3;
+      }
+    }
+  else if (regno == 70)
+    {
+      return stpcpy (name, "fsr") + 1 - name;
+    }
+  else if (regno == 71)
+    {
+      return stpcpy (name, "fir") + 1 - name;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/backends/mips_retval.c b/backends/mips_retval.c
new file mode 100644
index 00000000..5984d072
--- /dev/null
+++ b/backends/mips_retval.c
@@ -0,0 +1,196 @@
+/* Function return value location for Linux/mips ABI.
+   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <string.h>
+#include <elf.h>
+#include <stdio.h>
+
+#define BACKEND mips_
+#include "libebl_CPU.h"
+#include "libdwP.h"
+#include <stdio.h>
+
+/* $v0 or pair $v0, $v1 */
+static const Dwarf_Op loc_intreg_o32[] =
+  {
+    { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 8 },
+    { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 8 },
+  };
+#define nloc_intreg	1
+#define nloc_intregpair	4
+
+/* $f0 (float), or pair $f0, $f1 (double).
+ * f2/f3 are used for COMPLEX (= 2 doubles) returns in Fortran */
+static const Dwarf_Op loc_fpreg_o32[] =
+  {
+    { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_regx, .number = 35 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+
+/* $f0, or pair $f0, $f2.  */
+static const Dwarf_Op loc_fpreg[] =
+  {
+    { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 8 },
+    { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 8 },
+  };
+#define nloc_fpreg  1
+#define nloc_fpregpair 4
+#define nloc_fpregquad 8
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in $v0.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg2, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+int
+mips_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  unsigned int regsize = (gelf_getclass (functypedie->cu->dbg->elf) == ELFCLASS32 ) ? 4 : 8;
+  if (!regsize)
+    return -2;
+
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+
+  Dwarf_Attribute attr_mem;
+  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type, &attr_mem);
+  if (attr == NULL)
+    /* The function has no return value, like a `void' function in C.  */
+    return 0;
+
+  Dwarf_Die die_mem;
+  Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
+  int tag = dwarf_tag (typedie);
+
+  /* Follow typedefs and qualifiers to get to the actual type.  */
+  while (tag == DW_TAG_typedef
+	 || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
+	 || tag == DW_TAG_restrict_type)
+    {
+      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+      typedie = dwarf_formref_die (attr, &die_mem);
+      tag = dwarf_tag (typedie);
+    }
+
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = dwarf_tag (typedie);
+	}
+      /* Fall through.  */
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    CASE_POINTER:
+      {
+	Dwarf_Word size;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+					 &attr_mem), &size) != 0)
+	  {
+	    if (dwarf_is_pointer (tag))
+	      size = regsize;
+	    else
+	      return -1;
+	  }
+	if (tag == DW_TAG_base_type)
+	  {
+	    Dwarf_Word encoding;
+	    if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+					     &attr_mem), &encoding) != 0)
+	      return -1;
+
+#define ARCH_LOC(loc, regsize) ((regsize) == 4 ? (loc ## _o32) : (loc))
+
+	    if (encoding == DW_ATE_float)
+	      {
+		*locp = ARCH_LOC(loc_fpreg, regsize);
+		if (size <= regsize)
+		  return nloc_fpreg;
+
+		if (size <= 2*regsize)
+		  return nloc_fpregpair;
+
+		if (size <= 4*regsize)
+		  return nloc_fpregquad;
+
+		goto aggregate;
+	      }
+	  }
+	*locp = ARCH_LOC(loc_intreg, regsize);
+	if (size <= regsize)
+	  return nloc_intreg;
+	if (size <= 2*regsize)
+	  return nloc_intregpair;
+
+	/* Else fall through. Shouldn't happen though (at least with gcc) */
+      }
+      FALLTHROUGH;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    case DW_TAG_array_type:
+    aggregate:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+    case DW_TAG_unspecified_type:
+      return 0;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
-- 
2.30.2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] Add support for MIPS
  2023-11-02  6:55 [PATCH v2 0/5] Add support for MIPS Ying Huang
                   ` (4 preceding siblings ...)
  2023-11-02  6:56 ` [PATCH v2 5/5] backends: Add register_info, return_value_location, core_note function " Ying Huang
@ 2023-11-03 11:56 ` Mark Wielaard
  2023-11-03 12:20   ` Mark Wielaard
  2023-11-09  3:00   ` Ying Huang
  5 siblings, 2 replies; 17+ messages in thread
From: Mark Wielaard @ 2023-11-03 11:56 UTC (permalink / raw)
  To: Ying Huang, elfutils-devel; +Cc: yunqiang.su

Hi Yimg,

On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
> This is a series of modifications about MIPS.
> Support src/readelf, strip, elflint, objdump related tools.

Thanks. What are the changes compared to v1?
https://patchwork.sourceware.org/project/elfutils/list/?series=18813

> Pass all previous test cases that failed due to MIPS non-support.
> The following are the test results on mips64el.
> # TOTAL: 271
> # PASS:  263
> # SKIP:  8
> # XFAIL: 0
> # FAIL:  0
> # XPASS: 0
> # ERROR: 0

That looks pretty good. What distro/gcc/glibc/kernel was this against?

Cheers,

Mark

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips
  2023-11-02  6:55 ` [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips Ying Huang
@ 2023-11-03 12:18   ` Mark Wielaard
  2024-02-10  0:20     ` Mark Wielaard
  0 siblings, 1 reply; 17+ messages in thread
From: Mark Wielaard @ 2023-11-03 12:18 UTC (permalink / raw)
  To: Ying Huang, elfutils-devel; +Cc: yunqiang.su

Hi Ying,

On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
> 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.

This part and the new backends hooks look OK.

>   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.

But I still have some trouble fully understanding this part. I
understand why you need it, as explained here:
https://patchwork.sourceware.org/project/elfutils/patch/20230411081141.1762395-2-ying.huang@oss.cipunited.com/#145284

But I still don't know if this is the right way to deal with it.
Given the elf_update part is generic I rather not apply it just before
doing a release (today). We could apply the other parts/patches which
generally look OK. But I think it is better to do it after 0.190 is
released (then people who need a mips64 backend have this patchset to
apply as a whole).

We'll make it a priority to get this in asap for 0.191 and try to make
sure it won't be too long (max 3 months) till the next release.

Cheers,

Mark

> ---
>  backends/Makefile.am    |   6 +-
>  backends/mips_init.c    |  52 ++++++++++++++++
>  backends/mips_reloc.def |  93 ++++++++++++++++++++++++++++
>  backends/mips_symbol.c  |  63 +++++++++++++++++++
>  libebl/eblopenbackend.c |   2 +
>  libelf/elf_getdata.c    | 132 +++++++++++++++++++++++++++++++++++++++-
>  libelf/elf_update.c     |  53 ++++++++++++++++
>  libelf/libelfP.h        |   3 +
>  8 files changed, 400 insertions(+), 4 deletions(-)
>  create mode 100644 backends/mips_init.c
>  create mode 100644 backends/mips_reloc.def
>  create mode 100644 backends/mips_symbol.c
> 
> 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 00000000..e26da609
> --- /dev/null
> +++ b/backends/mips_init.c
> @@ -0,0 +1,52 @@
> +/* Initialization of MIPS specific backend library.
> +   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
> +
> +#ifdef HAVE_CONFIG_H
> +# include <config.h>
> +#endif
> +
> +#define BACKEND		mips_
> +#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 00000000..8cb66a54
> --- /dev/null
> +++ b/backends/mips_reloc.def
> @@ -0,0 +1,93 @@
> +/* List the relocation types for MIPS.  -*- C -*-
> +   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
> +
> +/*	    NAME,		REL|EXEC|DYN	*/
> +
> +
> +RELOC_TYPE (NONE,		REL|EXEC|DYN)
> +RELOC_TYPE (16,		        REL|EXEC|DYN)
> +RELOC_TYPE (32,	                REL)
> +RELOC_TYPE (REL32,	        REL|EXEC|DYN)
> +RELOC_TYPE (26,		        REL|DYN)
> +RELOC_TYPE (HI16,	        REL)
> +RELOC_TYPE (LO16,		REL|EXEC|DYN)
> +RELOC_TYPE (GPREL16,		REL|EXEC|DYN)
> +RELOC_TYPE (LITERAL,		REL|EXEC|DYN)
> +RELOC_TYPE (GOT16,		REL|EXEC|DYN)
> +RELOC_TYPE (PC16,		REL)
> +RELOC_TYPE (CALL16,		REL)
> +RELOC_TYPE (GPREL32,		REL)
> +RELOC_TYPE (SHIFT5,		REL)
> +RELOC_TYPE (SHIFT6,		REL)
> +RELOC_TYPE (64,		        REL)
> +RELOC_TYPE (GOT_DISP,		REL)
> +RELOC_TYPE (GOT_PAGE,		REL)
> +RELOC_TYPE (GOT_OFST,		REL)
> +RELOC_TYPE (GOT_HI16,		REL)
> +RELOC_TYPE (GOT_LO16,		REL)
> +RELOC_TYPE (SUB,		REL)
> +RELOC_TYPE (INSERT_A,		REL)
> +RELOC_TYPE (INSERT_B,		REL)
> +RELOC_TYPE (DELETE,		REL)
> +RELOC_TYPE (HIGHER,		REL)
> +RELOC_TYPE (HIGHEST,		REL)
> +RELOC_TYPE (CALL_HI16,		REL)
> +RELOC_TYPE (CALL_LO16,		REL)
> +RELOC_TYPE (SCN_DISP,		REL)
> +RELOC_TYPE (REL16,		REL)
> +RELOC_TYPE (ADD_IMMEDIATE,	REL)
> +RELOC_TYPE (PJUMP,		REL)
> +RELOC_TYPE (RELGOT,		REL)
> +RELOC_TYPE (JALR,		REL)
> +RELOC_TYPE (TLS_DTPMOD32,	DYN)
> +RELOC_TYPE (TLS_DTPREL32,	REL)
> +RELOC_TYPE (TLS_DTPMOD64,	DYN)
> +RELOC_TYPE (TLS_DTPREL64,	REL)
> +RELOC_TYPE (TLS_GD,		REL)
> +RELOC_TYPE (TLS_LDM,		REL)
> +RELOC_TYPE (TLS_DTPREL_HI16,	REL)
> +RELOC_TYPE (TLS_DTPREL_LO16,	REL)
> +RELOC_TYPE (TLS_GOTTPREL,	REL)
> +RELOC_TYPE (TLS_TPREL32,	REL)
> +RELOC_TYPE (TLS_TPREL64,	REL)
> +RELOC_TYPE (TLS_TPREL_HI16,	REL)
> +RELOC_TYPE (TLS_TPREL_LO16,	REL)
> +RELOC_TYPE (GLOB_DAT,		REL)
> +RELOC_TYPE (PC21_S2,		REL)
> +RELOC_TYPE (PC26_S2,		REL)
> +RELOC_TYPE (PC18_S3,		REL)
> +RELOC_TYPE (PC19_S2,		REL)
> +RELOC_TYPE (PCHI16,		REL)
> +RELOC_TYPE (PCLO16,		REL)
> +RELOC_TYPE (COPY,		REL)
> +RELOC_TYPE (JUMP_SLOT,		REL)
> +RELOC_TYPE (PC32,		REL)
> +RELOC_TYPE (EH,			REL)
> +RELOC_TYPE (GNU_REL16_S2,	REL)
> +RELOC_TYPE (GNU_VTINHERIT,	REL)
> +RELOC_TYPE (GNU_VTENTRY,	REL)
> diff --git a/backends/mips_symbol.c b/backends/mips_symbol.c
> new file mode 100644
> index 00000000..a9dd5c09
> --- /dev/null
> +++ b/backends/mips_symbol.c
> @@ -0,0 +1,63 @@
> +/* MIPS specific symbolic name handling.
> +   Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.  */
> +
> +#ifdef HAVE_CONFIG_H
> +# include <config.h>
> +#endif
> +
> +#include <system.h>
> +
> +#include <elf.h>
> +#include <stddef.h>
> +#include <string.h>
> +#include <stdio.h>
> +#define BACKEND		mips_
> +#include "libebl_CPU.h"
> +#include "libelfP.h"
> +
> +/* Check for the simple reloc types.  */
> +Elf_Type
> +mips_reloc_simple_type (Ebl *ebl, int type,
> +			   int *addsub __attribute__ ((unused)))
> +{
> +  int typeNew = type;
> +  if(ebl->elf->class == ELFCLASS64)
> +    typeNew = ELF64_MIPS_R_TYPE1(type);
> +  switch (typeNew)
> +    {
> +    case R_MIPS_64:
> +      return ELF_T_XWORD;
> +    case R_MIPS_32:
> +      return ELF_T_WORD;
> +    case R_MIPS_16:
> +      return ELF_T_HALF;
> +
> +    default:
> +      return ELF_T_NUM;
> +    }
> +}
> diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
> index 084a1544..a5f7467a 100644
> --- a/libebl/eblopenbackend.c
> +++ b/libebl/eblopenbackend.c
> @@ -57,6 +57,7 @@ Ebl *riscv_init (Elf *, GElf_Half, Ebl *);
>  Ebl *csky_init (Elf *, GElf_Half, Ebl *);
>  Ebl *loongarch_init (Elf *, GElf_Half, Ebl *);
>  Ebl *arc_init (Elf *, GElf_Half, Ebl *);
> +Ebl *mips_init (Elf *, GElf_Half, Ebl *);
>  
>  /* This table should contain the complete list of architectures as far
>     as the ELF specification is concerned.  */
> @@ -154,6 +155,7 @@ static const struct
>    { csky_init, "elf_csky", "csky", 4, EM_CSKY, ELFCLASS32, ELFDATA2LSB },
>    { loongarch_init, "elf_loongarch", "loongarch", 9, EM_LOONGARCH, ELFCLASS64, ELFDATA2LSB },
>    { arc_init, "elf_arc", "arc", 3, EM_ARCV2, ELFCLASS32, ELFDATA2LSB },
> +  { mips_init, "elf_mips", "mips", 4, EM_MIPS, 0, 0 },
>  };
>  #define nmachines (sizeof (machines) / sizeof (machines[0]))
>  
> 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 & 0xffffffff) << 32)
> +			| ((info >> 56) & 0xff)
> +			| ((info >> 40) & 0xff00)
> +			| ((info >> 24) & 0xff0000)
> +			| ((info >> 8) & 0xff000000));
> +	  ((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 = 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_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
> +	    Elf64_Xword info = value->r_info;
> +	    value->r_info = (((info & 0xffffffff) << 32)
> +			| ((info >> 56) & 0xff)
> +			| ((info >> 40) & 0xff00)
> +			| ((info >> 24) & 0xff0000)
> +			| ((info >> 8) & 0xff000000));
> +	    ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
> +	  }
> +      }
> +}
> +
>  /* Convert the data in the current section.  */
>  static void
>  convert_data (Elf_Scn *scn, int eclass,
> @@ -451,8 +564,23 @@ __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
>  	    return;
>  	}
>  
> -      /* Convert according to the version and the type.   */
> -      convert_data (scn, elf->class,
> +      GElf_Shdr shdr_mem;
> +      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
> +      GElf_Ehdr ehdr_mem;
> +      GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
> +      if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
> +	  scn->elf->class == ELFCLASS64 && ehdr != NULL &&
> +	  ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
> +	convert_data_for_mips64el (scn, elf->class,
> +		    (elf->class == ELFCLASS32
> +		     || (offsetof (struct Elf, state.elf32.ehdr)
> +			 == offsetof (struct Elf, state.elf64.ehdr))
> +		     ? elf->state.elf32.ehdr->e_ident[EI_DATA]
> +		     : elf->state.elf64.ehdr->e_ident[EI_DATA]),
> +		    scn->rawdata.d.d_size, scn->rawdata.d.d_type);
> +      else
> +	/* Convert according to the version and the type.   */
> +	convert_data (scn, elf->class,
>  		    (elf->class == ELFCLASS32
>  		     || (offsetof (struct Elf, state.elf32.ehdr)
>  			 == offsetof (struct Elf, state.elf64.ehdr))
> diff --git a/libelf/elf_update.c b/libelf/elf_update.c
> index 56af3a1c..aec19b7c 100644
> --- a/libelf/elf_update.c
> +++ b/libelf/elf_update.c
> @@ -228,7 +228,60 @@ elf_update (Elf *elf, Elf_Cmd cmd)
>  	  size = -1;
>  	}
>        else
> +	{
> +	  /* 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. */
> +	  Elf_Scn *scn = NULL;
> +	  while ((scn = elf_nextscn (elf, scn)) != NULL)
> +	    {
> +	      GElf_Shdr shdr_mem;
> +	      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
> +	      GElf_Ehdr ehdr_mem;
> +	      GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
> +	      if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
> +		scn->elf->class == ELFCLASS64 &&
> +		ehdr != NULL && ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
> +		{
> +		  Elf_Data *d = elf_getdata (scn, NULL);
> +		  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 *) d;
> +			  Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
> +			  Elf64_Xword info = value->r_info;
> +			  value->r_info = (info >> 32
> +					| ((info << 56) & 0xff00000000000000)
> +					| ((info << 40) & 0xff000000000000)
> +					| ((info << 24) & 0xff0000000000)
> +					| ((info << 8) & 0xff00000000));
> +			  ((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 = shdr->sh_size / sh_entsize;
> +		      for (int cnt = 0; cnt < nentries; cnt++)
> +			{
> +			  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) d;
> +			  Elf64_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
> +			  Elf64_Xword info = value->r_info;
> +			  value->r_info = (info >> 32
> +					| ((info << 56) & 0xff00000000000000)
> +					| ((info << 40) & 0xff000000000000)
> +					| ((info << 24) & 0xff0000000000)
> +					| ((info << 8) & 0xff00000000));
> +			  ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
> +			}
> +		    }
> +		}
> +	    }
>  	size = write_file (elf, size, change_bo, shnum);
> +      }
>      }
>  
>   out:
> diff --git a/libelf/libelfP.h b/libelf/libelfP.h
> index ed061abb..bdd2cc6a 100644
> --- a/libelf/libelfP.h
> +++ b/libelf/libelfP.h
> @@ -617,4 +617,7 @@ extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size,
>  #define INVALID_NDX(ndx, type, data) \
>    unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx))
>  
> +#define ELF64_MIPS_R_TYPE1(i)          ((i) & 0xff)
> +#define ELF64_MIPS_R_TYPE2(i)           (((i) >> 8) & 0xff)
> +#define ELF64_MIPS_R_TYPE3(i)           (((i) >> 16) & 0xff)
>  #endif  /* libelfP.h */


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] Add support for MIPS
  2023-11-03 11:56 ` [PATCH v2 0/5] Add support for MIPS Mark Wielaard
@ 2023-11-03 12:20   ` Mark Wielaard
  2023-11-09  3:00   ` Ying Huang
  1 sibling, 0 replies; 17+ messages in thread
From: Mark Wielaard @ 2023-11-03 12:20 UTC (permalink / raw)
  To: Ying Huang, elfutils-devel; +Cc: yunqiang.su

On Fri, 2023-11-03 at 12:56 +0100, Mark Wielaard wrote:
> Hi Yimg,

Sorry, typo, Ying.

> On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
> > This is a series of modifications about MIPS.
> > Support src/readelf, strip, elflint, objdump related tools.
> 
> Thanks. What are the changes compared to v1?
> https://patchwork.sourceware.org/project/elfutils/list/?series=18813

Sorry, I just marked this series as superseded, so the correct URL is:
https://patchwork.sourceware.org/project/elfutils/list/?series=18813&state=*

> > Pass all previous test cases that failed due to MIPS non-support.
> > The following are the test results on mips64el.
> > # TOTAL: 271
> > # PASS:  263
> > # SKIP:  8
> > # XFAIL: 0
> > # FAIL:  0
> > # XPASS: 0
> > # ERROR: 0
> 
> That looks pretty good. What distro/gcc/glibc/kernel was this against?
> 
> Cheers,
> 
> Mark


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] Add support for MIPS
  2023-11-03 11:56 ` [PATCH v2 0/5] Add support for MIPS Mark Wielaard
  2023-11-03 12:20   ` Mark Wielaard
@ 2023-11-09  3:00   ` Ying Huang
  2023-11-29  7:40     ` Ying Huang
  2024-01-23  8:21     ` Ying Huang
  1 sibling, 2 replies; 17+ messages in thread
From: Ying Huang @ 2023-11-09  3:00 UTC (permalink / raw)
  To: Mark Wielaard, elfutils-devel; +Cc: yunqiang.su

Hi,

在 2023/11/3 19:56, Mark Wielaard 写道:
> Hi Yimg,
>
> On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
>> This is a series of modifications about MIPS.
>> Support src/readelf, strip, elflint, objdump related tools.
> Thanks. What are the changes compared to v1?
> https://patchwork.sourceware.org/project/elfutils/list/?series=18813
>
>> Pass all previous test cases that failed due to MIPS non-support.
>> The following are the test results on mips64el.
>> # TOTAL: 271
>> # PASS:  263
>> # SKIP:  8
>> # XFAIL: 0
>> # FAIL:  0
>> # XPASS: 0
>> # ERROR: 0
> That looks pretty good. What distro/gcc/glibc/kernel was this against?
>
> Cheers,
>
> Mark

Debian GNU/Linux 11

gcc version 12.2.0

glibc  2.36-9

kernel version 5.10.0-22-loongson-3


Thanks,

Ying

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] Add support for MIPS
  2023-11-09  3:00   ` Ying Huang
@ 2023-11-29  7:40     ` Ying Huang
  2023-12-19  2:53       ` Ying Huang
  2024-01-23  8:21     ` Ying Huang
  1 sibling, 1 reply; 17+ messages in thread
From: Ying Huang @ 2023-11-29  7:40 UTC (permalink / raw)
  To: Mark Wielaard, elfutils-devel; +Cc: yunqiang.su

Ping


Thanks,

Ying


在 2023/11/9 11:00, Ying Huang 写道:
> Hi,
>
> 在 2023/11/3 19:56, Mark Wielaard 写道:
>> Hi Yimg,
>>
>> On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
>>> This is a series of modifications about MIPS.
>>> Support src/readelf, strip, elflint, objdump related tools.
>> Thanks. What are the changes compared to v1?
>> https://patchwork.sourceware.org/project/elfutils/list/?series=18813
>>
>>> Pass all previous test cases that failed due to MIPS non-support.
>>> The following are the test results on mips64el.
>>> # TOTAL: 271
>>> # PASS:  263
>>> # SKIP:  8
>>> # XFAIL: 0
>>> # FAIL:  0
>>> # XPASS: 0
>>> # ERROR: 0
>> That looks pretty good. What distro/gcc/glibc/kernel was this against?
>>
>> Cheers,
>>
>> Mark
> Debian GNU/Linux 11
>
> gcc version 12.2.0
>
> glibc  2.36-9
>
> kernel version 5.10.0-22-loongson-3
>
>
> Thanks,
>
> Ying

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] Add support for MIPS
  2023-11-29  7:40     ` Ying Huang
@ 2023-12-19  2:53       ` Ying Huang
  2023-12-29  9:15         ` Ying Huang
  0 siblings, 1 reply; 17+ messages in thread
From: Ying Huang @ 2023-12-19  2:53 UTC (permalink / raw)
  To: Mark Wielaard, elfutils-devel

Ping


Thanks,

Ying


在 2023/11/29 15:40, Ying Huang 写道:
> Ping
>
>
> Thanks,
>
> Ying
>
>
> 在 2023/11/9 11:00, Ying Huang 写道:
>> Hi,
>>
>> 在 2023/11/3 19:56, Mark Wielaard 写道:
>>> Hi Yimg,
>>>
>>> On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
>>>> This is a series of modifications about MIPS.
>>>> Support src/readelf, strip, elflint, objdump related tools.
>>> Thanks. What are the changes compared to v1?
>>> https://patchwork.sourceware.org/project/elfutils/list/?series=18813
>>>
>>>> Pass all previous test cases that failed due to MIPS non-support.
>>>> The following are the test results on mips64el.
>>>> # TOTAL: 271
>>>> # PASS:  263
>>>> # SKIP:  8
>>>> # XFAIL: 0
>>>> # FAIL:  0
>>>> # XPASS: 0
>>>> # ERROR: 0
>>> That looks pretty good. What distro/gcc/glibc/kernel was this against?
>>>
>>> Cheers,
>>>
>>> Mark
>> Debian GNU/Linux 11
>>
>> gcc version 12.2.0
>>
>> glibc  2.36-9
>>
>> kernel version 5.10.0-22-loongson-3
>>
>>
>> Thanks,
>>
>> Ying

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] Add support for MIPS
  2023-12-19  2:53       ` Ying Huang
@ 2023-12-29  9:15         ` Ying Huang
  0 siblings, 0 replies; 17+ messages in thread
From: Ying Huang @ 2023-12-29  9:15 UTC (permalink / raw)
  To: Mark Wielaard, elfutils-devel

Ping


Thanks,

Ying.

>>>>> Pass all previous test cases that failed due to MIPS non-support.
>>>>> The following are the test results on mips64el.
>>>>> # TOTAL: 271
>>>>> # PASS:  263
>>>>> # SKIP:  8
>>>>> # XFAIL: 0
>>>>> # FAIL:  0
>>>>> # XPASS: 0
>>>>> # ERROR: 0
>>>> That looks pretty good. What distro/gcc/glibc/kernel was this against?
>>>>
>>>> Cheers,
>>>>
>>>> Mark
>>> Debian GNU/Linux 11
>>>
>>> gcc version 12.2.0
>>>
>>> glibc  2.36-9
>>>
>>> kernel version 5.10.0-22-loongson-3
>>>
>>>
>>> Thanks,
>>>
>>> Ying

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] Add support for MIPS
  2023-11-09  3:00   ` Ying Huang
  2023-11-29  7:40     ` Ying Huang
@ 2024-01-23  8:21     ` Ying Huang
  2024-02-04  1:44       ` Ying Huang
  1 sibling, 1 reply; 17+ messages in thread
From: Ying Huang @ 2024-01-23  8:21 UTC (permalink / raw)
  To: Mark Wielaard, elfutils-devel

Ping,

Thanks.


在 2023/11/9 11:00, Ying Huang 写道:
> Hi,
>
> 在 2023/11/3 19:56, Mark Wielaard 写道:
>> Hi Yimg,
>>
>> On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
>>> This is a series of modifications about MIPS.
>>> Support src/readelf, strip, elflint, objdump related tools.
>> Thanks. What are the changes compared to v1?
>> https://patchwork.sourceware.org/project/elfutils/list/?series=18813
>>
>>> Pass all previous test cases that failed due to MIPS non-support.
>>> The following are the test results on mips64el.
>>> # TOTAL: 271
>>> # PASS:  263
>>> # SKIP:  8
>>> # XFAIL: 0
>>> # FAIL:  0
>>> # XPASS: 0
>>> # ERROR: 0
>> That looks pretty good. What distro/gcc/glibc/kernel was this against?
>>
>> Cheers,
>>
>> Mark
> Debian GNU/Linux 11
>
> gcc version 12.2.0
>
> glibc  2.36-9
>
> kernel version 5.10.0-22-loongson-3
>
>
> Thanks,
>
> Ying

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/5] Add support for MIPS
  2024-01-23  8:21     ` Ying Huang
@ 2024-02-04  1:44       ` Ying Huang
  0 siblings, 0 replies; 17+ messages in thread
From: Ying Huang @ 2024-02-04  1:44 UTC (permalink / raw)
  To: Mark Wielaard, elfutils-devel

Hi Mark,

The email responded to the question you aksed last time about the test environment.   Patch v2 has modified all the questions you asked in the patch v1.

Could you help reivew it again when you have time? If you have any questions, please feel free to let me konw.

Thanks,

Ying


在 2024/1/23 16:21, Ying Huang 写道:
> Ping,
>
> Thanks.
>
>
> 在 2023/11/9 11:00, Ying Huang 写道:
>> Hi,
>>
>> 在 2023/11/3 19:56, Mark Wielaard 写道:
>>> Hi Yimg,
>>>
>>> On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
>>>> This is a series of modifications about MIPS.
>>>> Support src/readelf, strip, elflint, objdump related tools.
>>> Thanks. What are the changes compared to v1?
>>> https://patchwork.sourceware.org/project/elfutils/list/?series=18813
>>>
>>>> Pass all previous test cases that failed due to MIPS non-support.
>>>> The following are the test results on mips64el.
>>>> # TOTAL: 271
>>>> # PASS:  263
>>>> # SKIP:  8
>>>> # XFAIL: 0
>>>> # FAIL:  0
>>>> # XPASS: 0
>>>> # ERROR: 0
>>> That looks pretty good. What distro/gcc/glibc/kernel was this against?
>>>
>>> Cheers,
>>>
>>> Mark
>> Debian GNU/Linux 11
>>
>> gcc version 12.2.0
>>
>> glibc  2.36-9
>>
>> kernel version 5.10.0-22-loongson-3
>>
>>
>> Thanks,
>>
>> Ying

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips
  2023-11-03 12:18   ` Mark Wielaard
@ 2024-02-10  0:20     ` Mark Wielaard
  2024-02-18  7:22       ` Ying Huang
  0 siblings, 1 reply; 17+ messages in thread
From: Mark Wielaard @ 2024-02-10  0:20 UTC (permalink / raw)
  To: Ying Huang, elfutils-devel; +Cc: yunqiang.su

Hi Ying,

Sorry I keep postponing this. I don't have access to a mips64le box,
the cfarm only has 64bit big endian mips machines. But the part I am
struggling with is the relocation data conversion needed in the
mips64le case.

On Fri, Nov 03, 2023 at 01:18:12PM +0100, Mark Wielaard wrote:
> On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
> > 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.
> 
> This part and the new backends hooks look OK.

So to make progress could you split this part?  Just a patch that adds
the initial mips backend (and the libebl and libelfP.h parts). And
another that introduces the libelf/elf_update and elf_getdata parts?

Also could you take a look at CONTRIBUTING
https://sourceware.org/cgit/elfutils/tree/CONTRIBUTING
And provide a Signed-off-by line if you can/agree with that?

Which MIPS variant(s) have you tested this against?  Is it supposed to
only work for mips64le? Or also maps64[be] and/or mips32 bits?

Thanks,

Mark

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips
  2024-02-10  0:20     ` Mark Wielaard
@ 2024-02-18  7:22       ` Ying Huang
  0 siblings, 0 replies; 17+ messages in thread
From: Ying Huang @ 2024-02-18  7:22 UTC (permalink / raw)
  To: Mark Wielaard, elfutils-devel

Hi  Mark,

在 2024/2/10 08:20, Mark Wielaard 写道:
> Hi Ying,
>
> Sorry I keep postponing this. I don't have access to a mips64le box,
> the cfarm only has 64bit big endian mips machines. But the part I am
> struggling with is the relocation data conversion needed in the
> mips64le case.
>
> On Fri, Nov 03, 2023 at 01:18:12PM +0100, Mark Wielaard wrote:
>> On Thu, 2023-11-02 at 14:55 +0800, Ying Huang wrote:
>>> 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.
>> This part and the new backends hooks look OK.
> So to make progress could you split this part?  Just a patch that adds
> the initial mips backend (and the libebl and libelfP.h parts). And
> another that introduces the libelf/elf_update and elf_getdata parts?
OK, I would split it as you advised and submit patch v3.
> Also could you take a look at CONTRIBUTING
> https://sourceware.org/cgit/elfutils/tree/CONTRIBUTING
> And provide a Signed-off-by line if you can/agree with that?

OK.

>
> Which MIPS variant(s) have you tested this against?  Is it supposed to
> only work for mips64le? Or also maps64[be] and/or mips32 bits?

I had tested patch v2 on mips64el, mips32el/be, arm64, amd64, i386,  and did not produce new fail tests.

Only the part about 'the relocation data conversion' work for mips64el.

Thanks,

Ying

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2024-02-18  7:22 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-02  6:55 [PATCH v2 0/5] Add support for MIPS Ying Huang
2023-11-02  6:55 ` [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips Ying Huang
2023-11-03 12:18   ` Mark Wielaard
2024-02-10  0:20     ` Mark Wielaard
2024-02-18  7:22       ` Ying Huang
2023-11-02  6:55 ` [PATCH v2 2/5] readelf: Adapt src/readelf -h/-S/-r/-w/-l/-d/-a " Ying Huang
2023-11-02  6:56 ` [PATCH v2 3/5] elflint: adapt src/elflint --gnu src/nm " Ying Huang
2023-11-02  6:56 ` [PATCH v2 4/5] stack: Fix stack unwind failure " Ying Huang
2023-11-02  6:56 ` [PATCH v2 5/5] backends: Add register_info, return_value_location, core_note function " Ying Huang
2023-11-03 11:56 ` [PATCH v2 0/5] Add support for MIPS Mark Wielaard
2023-11-03 12:20   ` Mark Wielaard
2023-11-09  3:00   ` Ying Huang
2023-11-29  7:40     ` Ying Huang
2023-12-19  2:53       ` Ying Huang
2023-12-29  9:15         ` Ying Huang
2024-01-23  8:21     ` Ying Huang
2024-02-04  1:44       ` Ying Huang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).