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.hu...@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 */

Reply via email to