From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 69E0B3858D37 for ; Fri, 3 Nov 2023 12:18:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 69E0B3858D37 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 69E0B3858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=45.83.234.184 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699013909; cv=none; b=TNM7ScIV/k8cQEfbf0UzSCvAfAA6ZYHX7X/p2NF9WA24g/9w0cFUxYxxQYgqvfJTNhN9iMAZcjRMnyaaPz784UFajn8bMqkVrBH4X1bmqFgb830CsqoOkxfszo0H7EbORmfiYa6lc9LdhWKPvW6eQ46HBCtnJxLyLH3QHuA3a0c= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699013909; c=relaxed/simple; bh=+QepzjrGmqOKHmLFayhI/VbL6DyF74q52YJhKgEY1hA=; h=Message-ID:Subject:From:To:Date:MIME-Version; b=tlSYeBb6C26XKxZawh1kZXo6KTupPCUH+C3lgRSEVI0TW5P6TTkcf1KBZuTJAHpljIgr2SBpxD3WBJSned8xQeQQ+Bkoq1ec6yJjOp846MTsbuLVAn2o0yYGuuRskMhJqmSNQ9MExi0FN/AO/2xk1M6JGcVd5hb7hOYjYsjE8TQ= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id D81D1302FDC3; Fri, 3 Nov 2023 13:18:12 +0100 (CET) Received: by r6.localdomain (Postfix, from userid 1000) id 83CED34032A; Fri, 3 Nov 2023 13:18:12 +0100 (CET) Message-ID: <6ed6da0bf43349ad36a41da2fd05a8cd858261f9.camel@klomp.org> Subject: Re: [PATCH v2 1/5] strip: Adapt src/strip -o -f on mips From: Mark Wielaard To: Ying Huang , elfutils-devel@sourceware.org Cc: yunqiang.su@oss.cipunited.com Date: Fri, 03 Nov 2023 13:18:12 +0100 In-Reply-To: <20231102065602.3128526-2-ying.huang@oss.cipunited.com> References: <20231102065602.3128526-1-ying.huang@oss.cipunited.com> <20231102065602.3128526-2-ying.huang@oss.cipunited.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.48.4 (3.48.4-1.fc38) MIME-Version: 1.0 X-Spam-Status: No, score=-3033.3 required=5.0 tests=BAYES_00,GIT_PATCH_0,JMQ_SPF_NEUTRAL,KAM_DMARC_STATUS,KAM_SHORT,RCVD_IN_BARRACUDACENTRAL,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: 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.1762= 395-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 >=20 > 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 +=3D -I$(top_srcdir)/libebl -I$(top_srcdir)= /libasm \ > noinst_LIBRARIES =3D libebl_backends.a libebl_backends_pic.a > =20 > modules =3D 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 > =20 > i386_SRCS =3D 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 =3D loongarch_init.c loongarch_symbo= l.c loongarch_cfi.c \ > =20 > arc_SRCS =3D arc_init.c arc_symbol.c > =20 > +mips_SRCS =3D mips_init.c mips_symbol.c > + > libebl_backends_a_SOURCES =3D $(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) > =20 > libebl_backends_pic_a_SOURCES =3D > am_libebl_backends_pic_a_OBJECTS =3D $(libebl_backends_a_SOURCES:.c=3D.o= s) > 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 . */ > + > +#ifdef HAVE_CONFIG_H > +# include > +#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 . */ > + > +/* 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 . */ > + > +#ifdef HAVE_CONFIG_H > +# include > +#endif > + > +#include > + > +#include > +#include > +#include > +#include > +#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 =3D type; > + if(ebl->elf->class =3D=3D ELFCLASS64) > + typeNew =3D 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 *); > =20 > /* 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, ELFCL= ASS64, 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])) > =20 > 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, G= Elf_Xword align) > } > } > =20 > +/* 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 =3D=3D MY_ELFDATA || type =3D=3D ELF_T_BYTE) > + { > + /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, n= eed to convert > + relocation info(raw data). Some eu-utils use read-mmap method to map fi= le, so > + we need to malloc and memcpy raw data to avoid segment fault. After mod= ification, > + the correct value are saved in the malloced memory not in process addre= ss space. */ > + scn->data_base =3D malloc (size); > + if (scn->data_base =3D=3D 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 =3D malloc (size); > + if (scn->data_base =3D=3D 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, n= eed to convert > + relocation info(raw data). Some eu-utils use read-mmap method to map fi= le, so > + we need to malloc and memcpy raw data to avoid segment fault. After mod= ification, > + the correct value are saved in the malloced memory not in process addre= ss space. */ > + rawdata_source =3D malloc (size); > + if (rawdata_source =3D=3D 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 =3D __elf_xfctstom[eclass - 1][type]; > + > + fp (scn->data_base, rawdata_source, size, 0); > + > + if (rawdata_source !=3D scn->rawdata_base) > + free (rawdata_source); > + } > + > + scn->data_list.data.d.d_buf =3D scn->data_base; > + scn->data_list.data.d.d_size =3D size; > + scn->data_list.data.d.d_type =3D type; > + scn->data_list.data.d.d_off =3D scn->rawdata.d.d_off; > + scn->data_list.data.d.d_align =3D scn->rawdata.d.d_align; > + scn->data_list.data.d.d_version =3D scn->rawdata.d.d_version; > + > + scn->data_list.data.s =3D scn; > + > + /* In mips64 little-endian, r_info consists of four byte fields(contai= ns > + 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 s= ymbol > + 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 =3D gelf_getshdr (scn, &shdr_mem); > + if (shdr->sh_type =3D=3D SHT_REL) > + { > + size_t sh_entsize =3D gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CURRE= NT); > + int nentries =3D shdr->sh_size / sh_entsize; > + for (int cnt =3D 0; cnt < nentries; ++cnt) > + { > + Elf_Data_Scn *data_scn =3D (Elf_Data_Scn *) &scn->data_list.data.d; > + Elf64_Rel *value =3D &((Elf64_Rel *) data_scn->d.d_buf)[cnt]; > + Elf64_Xword info =3D value->r_info; > + value->r_info =3D (((info & 0xffffffff) << 32) > + | ((info >> 56) & 0xff) > + | ((info >> 40) & 0xff00) > + | ((info >> 24) & 0xff0000) > + | ((info >> 8) & 0xff000000)); > + ((Elf64_Rel *) data_scn->d.d_buf)[cnt] =3D *value; > + } > + } > + else if (shdr->sh_type =3D=3D SHT_RELA) > + { > + size_t sh_entsize =3D gelf_fsize (scn->elf, ELF_T_RELA, 1, EV_CURRENT); > + int nentries =3D shdr->sh_size / sh_entsize; > + for (int cnt =3D 0; cnt < nentries; cnt++) > + { > + Elf_Data_Scn *data_scn =3D (Elf_Data_Scn *) &scn->data_list.data.d; > + Elf64_Rela *value =3D &((Elf64_Rela *) data_scn->d.d_buf)[cnt]; > + Elf64_Xword info =3D value->r_info; > + value->r_info =3D (((info & 0xffffffff) << 32) > + | ((info >> 56) & 0xff) > + | ((info >> 40) & 0xff00) > + | ((info >> 24) & 0xff0000) > + | ((info >> 8) & 0xff000000)); > + ((Elf64_Rela *) data_scn->d.d_buf)[cnt] =3D *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 wrl= ocked) > return; > } > =20 > - /* Convert according to the version and the type. */ > - convert_data (scn, elf->class, > + GElf_Shdr shdr_mem; > + GElf_Shdr *shdr =3D gelf_getshdr (scn, &shdr_mem); > + GElf_Ehdr ehdr_mem; > + GElf_Ehdr *ehdr =3D gelf_getehdr (scn->elf, &ehdr_mem); > + if (shdr !=3D NULL && (shdr->sh_type =3D=3D SHT_RELA || shdr->sh_t= ype =3D=3D SHT_REL) && > + scn->elf->class =3D=3D ELFCLASS64 && ehdr !=3D NULL && > + ehdr->e_machine =3D=3D EM_MIPS && ehdr->e_ident[EI_DATA] =3D=3D ELFDA= TA2LSB) > + convert_data_for_mips64el (scn, elf->class, > + (elf->class =3D=3D ELFCLASS32 > + || (offsetof (struct Elf, state.elf32.ehdr) > + =3D=3D 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 =3D=3D ELFCLASS32 > || (offsetof (struct Elf, state.elf32.ehdr) > =3D=3D 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 =3D -1; > } > else > + { > + /* Because we converted the relocation info in mips order when we cal= l elf_getdata.c, > + so we need to convert the modified data in original order bits bef= ore writing the > + data to the file. */ > + Elf_Scn *scn =3D NULL; > + while ((scn =3D elf_nextscn (elf, scn)) !=3D NULL) > + { > + GElf_Shdr shdr_mem; > + GElf_Shdr *shdr =3D gelf_getshdr (scn, &shdr_mem); > + GElf_Ehdr ehdr_mem; > + GElf_Ehdr *ehdr =3D gelf_getehdr (scn->elf, &ehdr_mem); > + if (shdr !=3D NULL && (shdr->sh_type =3D=3D SHT_RELA || shdr->sh_= type =3D=3D SHT_REL) && > + scn->elf->class =3D=3D ELFCLASS64 && > + ehdr !=3D NULL && ehdr->e_machine =3D=3D EM_MIPS && ehdr->e_ident[EI_D= ATA] =3D=3D ELFDATA2LSB) > + { > + Elf_Data *d =3D elf_getdata (scn, NULL); > + if (shdr->sh_type =3D=3D SHT_REL) > + { > + size_t sh_entsize =3D gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CUR= RENT); > + int nentries =3D shdr->sh_size / sh_entsize; > + for (int cnt =3D 0; cnt < nentries; ++cnt) > + { > + Elf_Data_Scn *data_scn =3D (Elf_Data_Scn *) d; > + Elf64_Rel *value =3D &((Elf64_Rel *) data_scn->d.d_buf)[cnt]; > + Elf64_Xword info =3D value->r_info; > + value->r_info =3D (info >> 32 > + | ((info << 56) & 0xff00000000000000) > + | ((info << 40) & 0xff000000000000) > + | ((info << 24) & 0xff0000000000) > + | ((info << 8) & 0xff00000000)); > + ((Elf64_Rel *) data_scn->d.d_buf)[cnt] =3D *value; > + } > + } > + else if (shdr->sh_type =3D=3D SHT_RELA) > + { > + size_t sh_entsize =3D gelf_fsize (scn->elf, ELF_T_RELA, 1, EV_CU= RRENT); > + int nentries =3D shdr->sh_size / sh_entsize; > + for (int cnt =3D 0; cnt < nentries; cnt++) > + { > + Elf_Data_Scn *data_scn =3D (Elf_Data_Scn *) d; > + Elf64_Rela *value =3D &((Elf64_Rela *) data_scn->d.d_buf)[cnt]; > + Elf64_Xword info =3D value->r_info; > + value->r_info =3D (info >> 32 > + | ((info << 56) & 0xff00000000000000) > + | ((info << 40) & 0xff000000000000) > + | ((info << 24) & 0xff0000000000) > + | ((info << 8) & 0xff00000000)); > + ((Elf64_Rela *) data_scn->d.d_buf)[cnt] =3D *value; > + } > + } > + } > + } > size =3D write_file (elf, size, change_bo, shnum); > + } > } > =20 > 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, voi= d *buf, size_t size, > #define INVALID_NDX(ndx, type, data) \ > unlikely ((data)->d_size / sizeof (type) <=3D (unsigned int) (ndx)) > =20 > +#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 */