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

Ying Huang ying.huang@oss.cipunited.com
Wed Jul 10 02:37:36 GMT 2024


Hi Mark,

I have done tests on mips32 littele/big endian and mips64 little endian(because now I did not have mips64 big endian lab).

Attached are the test results and I compared them.

This is the change I mentioned last time to replace file libelf/elf_getdata.c. What do you think of this change?

/*diff --git a/libelf/gelf_getrela.c b/libelf/gelf_getrela.c index d695f659..fd974bdf 100644 --- a/libelf/gelf_getrela.c +++ b/libelf/gelf_getrela.c @@ -90,8 +90,21 @@ gelf_getrela (Elf_Data *data, int ndx, GElf_Rela *dst) result = NULL; } else - result = memcpy (dst, &((Elf64_Rela *) data_scn->d.d_buf)[ndx], - sizeof (Elf64_Rela)); + { + result = memcpy (dst, &((Elf64_Rela *) data_scn->d.d_buf)[ndx], + sizeof (Elf64_Rela)); + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (scn->elf, &ehdr_mem); + if(ehdr != NULL && ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB) + { + Elf64_Xword info = dst->r_info; + dst->r_info = (((info & 0xffffffff) << 32) + | ((info >> 56) & 0xff) + | ((info >> 40) & 0xff00) + | ((info >> 24) & 0xff0000) + | ((info >> 8) & 0xff000000)); + } + } }*/ /*rwlock_unlock (scn->elf->lock);*/

/*diff --git a/libelf/gelf_update_rela.c b/libelf/gelf_update_rela.c index 88252703..592d74b9 100644 --- a/libelf/gelf_update_rela.c +++ b/libelf/gelf_update_rela.c @@ -96,7 +96,20 @@ gelf_update_rela (Elf_Data *dst, int ndx, GElf_Rela *src) goto out; } - ((Elf64_Rela *) data_scn->d.d_buf)[ndx] = *src; + GElf_Ehdr ehdr_mem; + GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (scn->elf, &ehdr_mem); + GElf_Rela rela = *src; + if(ehdr != NULL && ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB) + { + Elf64_Xword info = rela.r_info; + rela.r_info = (info >> 32 + | ((info << 56) & 0xff00000000000000) + | ((info << 40) & 0xff000000000000) + | ((info << 24) & 0xff0000000000) + | ((info << 8) & 0xff00000000)); + } + + ((Elf64_Rela *) data_scn->d.d_buf)[ndx] = rela; } result = 1;*/

1. Target: mips64el-linux-gnuabi64

huangying@Sleepygon:~/elf/elfutils_main$ cat mips64el_with_patch.log | grep FAIL
# XFAIL: 0
# FAIL:  1
FAIL: run-sysroot.sh
FAIL run-sysroot.sh (exit status: 1)

-------This failed test case is related to src/stack and was investigating.

huangying@Sleepygon:~/elf/elfutils_main$ cat mips64el_without_patch.log | grep FAIL
# XFAIL: 0
# FAIL:  7
FAIL: run-strip-strmerge.sh
FAIL run-strip-strmerge.sh (exit status: 1)
FAIL: run-strip-reloc-self.sh
FAIL run-strip-reloc-self.sh (exit status: 1)
FAIL: run-elflint-self.sh
FAIL run-elflint-self.sh (exit status: 1)
FAIL: run-varlocs-self.sh
FAIL run-varlocs-self.sh (exit status: 1)
FAIL: run-exprlocs-self.sh
FAIL run-exprlocs-self.sh (exit status: 1)
FAIL: run-reverse-sections-self.sh
FAIL run-reverse-sections-self.sh (exit status: 1)
FAIL: run-sysroot.sh
FAIL run-sysroot.sh (exit status: 1)


2. Target: mipsel-linux-gnu:

root@debian-sid-mipsel:~/elfutils_6# cat mips32el_with_patch.log | grep FAIL
# XFAIL: 0
# FAIL:  10
FAIL: run-bug1-test.sh
FAIL run-bug1-test.sh (exit status: 1)
FAIL: run-backtrace-native.sh
FAIL run-backtrace-native.sh (exit status: 1)
FAIL: run-backtrace-dwarf.sh
FAIL run-backtrace-dwarf.sh (exit status: 1)
FAIL: run-backtrace-native-core.sh
FAIL run-backtrace-native-core.sh (exit status: 1)
FAIL: run-deleted.sh
FAIL run-deleted.sh (exit status: 1)
FAIL: elfstrtab
FAIL elfstrtab (exit status: 1)
FAIL: dwfl-proc-attach
FAIL dwfl-proc-attach (exit status: 255)
FAIL: emptyfile
FAIL emptyfile (exit status: 1)
FAIL: run-copyadd-sections.sh
FAIL run-copyadd-sections.sh (exit status: 1)
FAIL: run-sysroot.sh
FAIL run-sysroot.sh (exit status: 1)

--------These failed test cases are because the docker container does not support some features.

root@debian-sid-mipsel:~/elfutils_6# cat mips32el_without_patch.log | grep FAIL
# XFAIL: 0
# FAIL:  14
*FAIL: run-strip-strmerge.sh
FAIL run-strip-strmerge.sh (exit status: 1)
FAIL: run-strip-reloc-self.sh
FAIL run-strip-reloc-self.sh (exit status: 1)
FAIL: run-elflint-self.sh
FAIL run-elflint-self.sh (exit status: 1)*
FAIL: run-bug1-test.sh
FAIL run-bug1-test.sh (exit status: 1)
FAIL: run-backtrace-native.sh
FAIL run-backtrace-native.sh (exit status: 1)
FAIL: run-backtrace-dwarf.sh
FAIL run-backtrace-dwarf.sh (exit status: 1)
FAIL: run-backtrace-native-core.sh
FAIL run-backtrace-native-core.sh (exit status: 1)
FAIL: run-deleted.sh
FAIL run-deleted.sh (exit status: 1)
FAIL: elfstrtab
FAIL elfstrtab (exit status: 1)
FAIL: dwfl-proc-attach
FAIL dwfl-proc-attach (exit status: 255)
FAIL: emptyfile
FAIL emptyfile (exit status: 1)
*FAIL: run-reverse-sections-self.sh
FAIL run-reverse-sections-self.sh (exit status: 1)*
FAIL: run-copyadd-sections.sh
FAIL run-copyadd-sections.sh (exit status: 1)
FAIL: run-sysroot.sh
FAIL run-sysroot.sh (exit status: 1)


3. Target: mips-linux-gnu

root@debian-sid-mipsbe:~/elfutils_main# cat mips32be_with_patch.log | grep FAIL
# XFAIL: 0
# FAIL:  11
FAIL: run-native-test.sh
FAIL run-native-test.sh (exit status: 1)
FAIL: run-bug1-test.sh
FAIL run-bug1-test.sh (exit status: 1)
FAIL: run-backtrace-native.sh
FAIL run-backtrace-native.sh (exit status: 1)
FAIL: run-backtrace-dwarf.sh
FAIL run-backtrace-dwarf.sh (exit status: 1)
FAIL: run-backtrace-native-core.sh
FAIL run-backtrace-native-core.sh (exit status: 1)
FAIL: run-deleted.sh
FAIL run-deleted.sh (exit status: 1)
FAIL: elfstrtab
FAIL elfstrtab (exit status: 1)
FAIL: dwfl-proc-attach
FAIL dwfl-proc-attach (exit status: 255)
FAIL: emptyfile
FAIL emptyfile (exit status: 1)
FAIL: run-copyadd-sections.sh
FAIL run-copyadd-sections.sh (exit status: 1)
FAIL: run-sysroot.sh
FAIL run-sysroot.sh (exit status: 1)
root@debian-sid-mipsbe:~/elfutils_main# cat mips32be_without_patch.log | grep FAIL
# XFAIL: 0
# FAIL:  15
*FAIL: run-strip-strmerge.sh
FAIL run-strip-strmerge.sh (exit status: 1)
FAIL: run-strip-reloc-self.sh
FAIL run-strip-reloc-self.sh (exit status: 1)
FAIL: run-elflint-self.sh
FAIL run-elflint-self.sh (exit status: 1)*
FAIL: run-native-test.sh
FAIL run-native-test.sh (exit status: 1)
FAIL: run-bug1-test.sh
FAIL run-bug1-test.sh (exit status: 1)
FAIL: run-backtrace-native.sh
FAIL run-backtrace-native.sh (exit status: 1)
FAIL: run-backtrace-dwarf.sh
FAIL run-backtrace-dwarf.sh (exit status: 1)
FAIL: run-backtrace-native-core.sh
FAIL run-backtrace-native-core.sh (exit status: 1)
FAIL: run-deleted.sh
FAIL run-deleted.sh (exit status: 1)
FAIL: elfstrtab
FAIL elfstrtab (exit status: 1)
FAIL: dwfl-proc-attach
FAIL dwfl-proc-attach (exit status: 255)
FAIL: emptyfile
FAIL emptyfile (exit status: 1)
*FAIL: run-reverse-sections-self.sh
FAIL run-reverse-sections-self.sh (exit status: 1)*
FAIL: run-copyadd-sections.sh
FAIL run-copyadd-sections.sh (exit status: 1)
FAIL: run-sysroot.sh
FAIL run-sysroot.sh (exit status: 1)

Thanks,

Ying


在 2024/3/5 17:51, 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.
>
> Signed-off-by: Ying Huang <ying.huang@oss.cipunited.com>
> ---
>  libelf/elf_getdata.c | 132 ++++++++++++++++++++++++++++++++++++++++++-
>  libelf/elf_update.c  |  53 +++++++++++++++++
>  2 files changed, 183 insertions(+), 2 deletions(-)
>
> diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
> index 7c3ac043..942ba536 100644
> --- a/libelf/elf_getdata.c
> +++ b/libelf/elf_getdata.c
> @@ -133,6 +133,119 @@ __libelf_data_type (GElf_Ehdr *ehdr, int sh_type, GElf_Xword align)
>      }
>  }
>  
> +/* Convert the data in the current section.  */
> +static void
> +convert_data_for_mips64el (Elf_Scn *scn, int eclass,
> +	      int data, size_t size, Elf_Type type)
> +{
> +  /* Do we need to convert the data and/or adjust for alignment?  */
> +  if (data == MY_ELFDATA || type == ELF_T_BYTE)
> +    {
> +      /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to convert
> +	relocation info(raw data). Some eu-utils use read-mmap method to map file, so
> +	we need to malloc and memcpy raw data to avoid segment fault. After modification,
> +	the correct value are saved in the malloced memory not in process address space. */
> +      scn->data_base = malloc (size);
> +      if (scn->data_base == NULL)
> +	{
> +	   __libelf_seterrno (ELF_E_NOMEM);
> +	  return;
> +	}
> +
> +      /* The copy will be appropriately aligned for direct access.  */
> +      memcpy (scn->data_base, scn->rawdata_base, size);
> +    }
> +  else
> +    {
> +      xfct_t fp;
> +
> +      scn->data_base = malloc (size);
> +      if (scn->data_base == NULL)
> +	{
> +	  __libelf_seterrno (ELF_E_NOMEM);
> +	  return;
> +	}
> +
> +      /* Make sure the source is correctly aligned for the conversion
> +	 function to directly access the data elements.  */
> +      char *rawdata_source;
> +      /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to convert
> +	relocation info(raw data). Some eu-utils use read-mmap method to map file, so
> +	we need to malloc and memcpy raw data to avoid segment fault. After modification,
> +	the correct value are saved in the malloced memory not in process address space. */
> +      rawdata_source = malloc (size);
> +      if (rawdata_source == NULL)
> +	{
> +	  __libelf_seterrno (ELF_E_NOMEM);
> +	  return;
> +	}
> +
> +      /* The copy will be appropriately aligned for direct access.  */
> +      memcpy (rawdata_source, scn->rawdata_base, size);
> +
> +      /* Get the conversion function.  */
> +      fp = __elf_xfctstom[eclass - 1][type];
> +
> +      fp (scn->data_base, rawdata_source, size, 0);
> +
> +      if (rawdata_source != scn->rawdata_base)
> +	free (rawdata_source);
> +    }
> +
> +  scn->data_list.data.d.d_buf = scn->data_base;
> +  scn->data_list.data.d.d_size = size;
> +  scn->data_list.data.d.d_type = type;
> +  scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
> +  scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
> +  scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
> +
> +  scn->data_list.data.s = scn;
> +
> +  /* In mips64 little-endian, r_info consists of four byte fields(contains
> +     three reloc types) and a 32-bit symbol index. In order to adapt
> +     GELF_R_SYM and GELF_R_TYPE, need to convert r_info to get correct symbol
> +     index and type. */
> +  /* references:
> +     https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf
> +     Page40 && Page41 */
> +  GElf_Shdr shdr_mem;
> +  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
> +  if (shdr->sh_type == SHT_REL)
> +    {
> +      size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CURRENT);
> +      int nentries = shdr->sh_size / sh_entsize;
> +      for (int cnt = 0; cnt < nentries; ++cnt)
> +	{
> +	  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) &scn->data_list.data.d;
> +	  Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
> +	  Elf64_Xword info = value->r_info;
> +	  value->r_info = (((info & 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:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mips64el_with_patch.log
Type: text/x-log
Size: 2449 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/elfutils-devel/attachments/20240710/3425a024/attachment-0006.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mips32be_without_patch.log
Type: text/x-log
Size: 33473 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/elfutils-devel/attachments/20240710/3425a024/attachment-0007.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mips32be_with_patch.log
Type: text/x-log
Size: 10003 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/elfutils-devel/attachments/20240710/3425a024/attachment-0008.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mips32el_without_patch.log
Type: text/x-log
Size: 31009 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/elfutils-devel/attachments/20240710/3425a024/attachment-0009.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mips32el_with_patch.log
Type: text/x-log
Size: 7602 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/elfutils-devel/attachments/20240710/3425a024/attachment-0010.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mips64el_without_patch.log
Type: text/x-log
Size: 1298808 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/elfutils-devel/attachments/20240710/3425a024/attachment-0011.bin>


More information about the Elfutils-devel mailing list