From owner-svn-src-stable@freebsd.org Fri Nov 9 21:45:45 2018 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 161DE110915C; Fri, 9 Nov 2018 21:45:45 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 76A808F8D6; Fri, 9 Nov 2018 21:45:44 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 49B2F199E0; Fri, 9 Nov 2018 21:45:44 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wA9LjhgO035326; Fri, 9 Nov 2018 21:45:43 GMT (envelope-from emaste@FreeBSD.org) Received: (from emaste@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wA9Ljg72035319; Fri, 9 Nov 2018 21:45:42 GMT (envelope-from emaste@FreeBSD.org) Message-Id: <201811092145.wA9Ljg72035319@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: emaste set sender to emaste@FreeBSD.org using -f From: Ed Maste Date: Fri, 9 Nov 2018 21:45:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r340309 - in stable/11: contrib/elftoolchain/elfcopy contrib/elftoolchain/libelf sys/sys X-SVN-Group: stable-11 X-SVN-Commit-Author: emaste X-SVN-Commit-Paths: in stable/11: contrib/elftoolchain/elfcopy contrib/elftoolchain/libelf sys/sys X-SVN-Commit-Revision: 340309 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 76A808F8D6 X-Spamd-Result: default: False [-106.87 / 200.00]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; ALLOW_DOMAIN_WHITELIST(-100.00)[FreeBSD.org]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[4]; TO_MATCH_ENVRCPT_ALL(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; MIME_GOOD(-0.10)[text/plain]; TO_DN_NONE(0.00)[]; HAS_XAW(0.00)[]; R_SPF_SOFTFAIL(0.00)[~all]; DMARC_NA(0.00)[FreeBSD.org]; RCVD_COUNT_THREE(0.00)[4]; MX_GOOD(-0.01)[cached: mx1.FreeBSD.org]; NEURAL_HAM_SHORT(-1.00)[-1.000,0]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; RCVD_TLS_LAST(0.00)[]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; IP_SCORE(-3.76)[ip: (-9.91), ipnet: 2610:1c1:1::/48(-4.93), asn: 11403(-3.87), country: US(-0.09)] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Nov 2018 21:45:45 -0000 Author: emaste Date: Fri Nov 9 21:45:42 2018 New Revision: 340309 URL: https://svnweb.freebsd.org/changeset/base/340309 Log: Fix objcopy for little-endian MIPS64 objects. MFC r338478 (jhb): Fix objcopy for little-endian MIPS64 objects. MIPS64 does not store the 'r_info' field of a relocation table entry as a 64-bit value consisting of a 32-bit symbol index in the high 32 bits and a 32-bit type in the low 32 bits as on other architectures. Instead, the 64-bit 'r_info' field is really a 32-bit symbol index followed by four individual byte type fields. For big-endian MIPS64, treating this as a 64-bit integer happens to be compatible with the layout expected by other architectures (symbol index in upper 32-bits of resulting "native" 64-bit integer). However, for little-endian MIPS64 the parsed 64-bit integer contains the symbol index in the low 32 bits and the 4 individual byte type fields in the upper 32-bits (but as if the upper 32-bits were byte-swapped). To cope, add two helper routines in gelf_getrel.c to translate between the correct native 'r_info' value and the value obtained after the normal byte-swap translation. Use these routines in gelf_getrel(), gelf_getrela(), gelf_update_rel(), and gelf_update_rela(). This fixes 'readelf -r' on little-endian MIPS64 objects which was previously decoding incorrect relocations as well as 'objcopy: invalid symbox index' warnings from objcopy when extracting debug symbols from kernel modules. Even with this fixed, objcopy was still crashing when trying to extract debug symbols from little-endian MIPS64 modules. The workaround in gelf_*rel*() depends on the current ELF object having a valid ELF header so that the 'e_machine' field can be compared against EM_MIPS. objcopy was parsing the relocation entries to possibly rewrite the 'r_info' fields in the update_relocs() function before writing the initial ELF header to the destination object file. Move the initial write of the ELF header earlier before copy_contents() so that update_relocs() uses the correct symbol index values. Note that this change should really go upstream. The binutils readelf source has a similar hack for MIPS64EL though I implemented this version from scratch using the MIPS64 ABI PDF as a reference. MFC r339083 (emaste): libelf: correct mips64el test to use ELF header libelf maintains two views of endianness: e_byteorder, and e_ident[EI_DATA] in the ELF header itself. e_byteorder is not always kept in sync, so use the ELF header endianness to test for mips64el. MFC r339473 (emaste): libelf: also test for 64-bit ELF in _libelf_is_mips64el Although _libelf_is_mips64el is only called in contexts where we've already checked that e_class is ELFCLASS64 but this may change in the future. Add a safety belt so that we don't access an invalid e_ehdr64 union member if it does. PR: 231790 Added: stable/11/contrib/elftoolchain/libelf/gelf_mips64el.c - copied, changed from r338478, head/contrib/elftoolchain/libelf/gelf_mips64el.c Modified: stable/11/contrib/elftoolchain/elfcopy/main.c stable/11/contrib/elftoolchain/libelf/Makefile stable/11/contrib/elftoolchain/libelf/_libelf.h stable/11/contrib/elftoolchain/libelf/gelf_rel.c stable/11/contrib/elftoolchain/libelf/gelf_rela.c stable/11/sys/sys/param.h Directory Properties: stable/11/ (props changed) Modified: stable/11/contrib/elftoolchain/elfcopy/main.c ============================================================================== --- stable/11/contrib/elftoolchain/elfcopy/main.c Fri Nov 9 21:41:23 2018 (r340308) +++ stable/11/contrib/elftoolchain/elfcopy/main.c Fri Nov 9 21:45:42 2018 (r340309) @@ -372,6 +372,14 @@ create_elf(struct elfcopy *ecp) create_symtab(ecp); /* + * Write the underlying ehdr. Note that it should be called + * before elf_setshstrndx() since it will overwrite e->e_shstrndx. + */ + if (gelf_update_ehdr(ecp->eout, &oeh) == 0) + errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", + elf_errmsg(-1)); + + /* * First processing of output sections: at this stage we copy the * content of each section from input to output object. Section * content will be modified and printed (mcs) if need. Also content of @@ -379,14 +387,6 @@ create_elf(struct elfcopy *ecp) * to symbol table changes. */ copy_content(ecp); - - /* - * Write the underlying ehdr. Note that it should be called - * before elf_setshstrndx() since it will overwrite e->e_shstrndx. - */ - if (gelf_update_ehdr(ecp->eout, &oeh) == 0) - errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", - elf_errmsg(-1)); /* Generate section name string table (.shstrtab). */ set_shstrtab(ecp); Modified: stable/11/contrib/elftoolchain/libelf/Makefile ============================================================================== --- stable/11/contrib/elftoolchain/libelf/Makefile Fri Nov 9 21:41:23 2018 (r340308) +++ stable/11/contrib/elftoolchain/libelf/Makefile Fri Nov 9 21:45:42 2018 (r340309) @@ -35,6 +35,7 @@ SRCS= elf.c \ gelf_ehdr.c \ gelf_getclass.c \ gelf_fsize.c \ + gelf_mips64el.c \ gelf_move.c \ gelf_phdr.c \ gelf_rel.c \ Modified: stable/11/contrib/elftoolchain/libelf/_libelf.h ============================================================================== --- stable/11/contrib/elftoolchain/libelf/_libelf.h Fri Nov 9 21:41:23 2018 (r340308) +++ stable/11/contrib/elftoolchain/libelf/_libelf.h Fri Nov 9 21:45:42 2018 (r340309) @@ -216,12 +216,15 @@ int (*_libelf_get_translator(Elf_Type _t, int _directi void *_libelf_getphdr(Elf *_e, int _elfclass); void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); void _libelf_init_elf(Elf *_e, Elf_Kind _kind); +int _libelf_is_mips64el(Elf *e); int _libelf_load_section_headers(Elf *e, void *ehdr); unsigned int _libelf_malign(Elf_Type _t, int _elfclass); Elf *_libelf_memory(unsigned char *_image, size_t _sz, int _reporterror); size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror); +Elf64_Xword _libelf_mips64el_r_info_tof(Elf64_Xword r_info); +Elf64_Xword _libelf_mips64el_r_info_tom(Elf64_Xword r_info); struct _Libelf_Data *_libelf_release_data(struct _Libelf_Data *_d); Elf *_libelf_release_elf(Elf *_e); Elf_Scn *_libelf_release_scn(Elf_Scn *_s); Copied and modified: stable/11/contrib/elftoolchain/libelf/gelf_mips64el.c (from r338478, head/contrib/elftoolchain/libelf/gelf_mips64el.c) ============================================================================== --- head/contrib/elftoolchain/libelf/gelf_mips64el.c Wed Sep 5 20:51:53 2018 (r338478, copy source) +++ stable/11/contrib/elftoolchain/libelf/gelf_mips64el.c Fri Nov 9 21:45:42 2018 (r340309) @@ -34,8 +34,9 @@ int _libelf_is_mips64el(Elf *e) { - return (e->e_kind == ELF_K_ELF && e->e_byteorder == ELFDATA2LSB && - e->e_u.e_elf.e_ehdr.e_ehdr64->e_machine == EM_MIPS); + return (e->e_kind == ELF_K_ELF && e->e_class == ELFCLASS64 && + e->e_u.e_elf.e_ehdr.e_ehdr64->e_machine == EM_MIPS && + e->e_u.e_elf.e_ehdr.e_ehdr64->e_ident[EI_DATA] == ELFDATA2LSB); } /* Modified: stable/11/contrib/elftoolchain/libelf/gelf_rel.c ============================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_rel.c Fri Nov 9 21:41:23 2018 (r340308) +++ stable/11/contrib/elftoolchain/libelf/gelf_rel.c Fri Nov 9 21:45:42 2018 (r340309) @@ -90,6 +90,9 @@ gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst) rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; *dst = *rel64; + + if (_libelf_is_mips64el(e)) + dst->r_info = _libelf_mips64el_r_info_tom(rel64->r_info); } return (dst); @@ -156,6 +159,9 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr) rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; *rel64 = *dr; + + if (_libelf_is_mips64el(e)) + rel64->r_info = _libelf_mips64el_r_info_tof(dr->r_info); } return (1); Modified: stable/11/contrib/elftoolchain/libelf/gelf_rela.c ============================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_rela.c Fri Nov 9 21:41:23 2018 (r340308) +++ stable/11/contrib/elftoolchain/libelf/gelf_rela.c Fri Nov 9 21:45:42 2018 (r340309) @@ -91,6 +91,10 @@ gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst) rela64 = (Elf64_Rela *) d->d_data.d_buf + ndx; *dst = *rela64; + + if (_libelf_is_mips64el(e)) + dst->r_info = + _libelf_mips64el_r_info_tom(rela64->r_info); } return (dst); @@ -159,6 +163,9 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr) rela64 = (Elf64_Rela *) d->d_data.d_buf + ndx; *rela64 = *dr; + + if (_libelf_is_mips64el(e)) + rela64->r_info = _libelf_mips64el_r_info_tof(dr->r_info); } return (1); Modified: stable/11/sys/sys/param.h ============================================================================== --- stable/11/sys/sys/param.h Fri Nov 9 21:41:23 2018 (r340308) +++ stable/11/sys/sys/param.h Fri Nov 9 21:45:42 2018 (r340309) @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1102503 /* Master, propagated to newvers */ +#define __FreeBSD_version 1102504 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,