Ping
Thanks, Ying 在 2024/7/29 17:56, Ying Huang 写道: > Ping > > > Thanks, > > Ying > > > 在 2024/7/10 10:37, Ying Huang 写道: >> 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.hu...@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.hu...@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: