Index: contrib/elftoolchain/libelf/Version.map =================================================================== --- contrib/elftoolchain/libelf/Version.map +++ contrib/elftoolchain/libelf/Version.map @@ -91,6 +91,13 @@ gelf_update_symshndx; gelf_xlatetof; gelf_xlatetom; +}; + +R1.1 { +global: + elf32_getchdr; + elf64_getchdr; + gelf_getchdr; local: *; -}; +} R1.0; Index: contrib/elftoolchain/libelf/_libelf.h =================================================================== --- contrib/elftoolchain/libelf/_libelf.h +++ contrib/elftoolchain/libelf/_libelf.h @@ -220,6 +220,7 @@ size_t count); _libelf_translator_function *_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass, int _elfmachine); +void *_libelf_getchdr(Elf_Scn *_e, int _elfclass); void *_libelf_getphdr(Elf *_e, int _elfclass); void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); void _libelf_init_elf(Elf *_e, Elf_Kind _kind); Index: contrib/elftoolchain/libelf/gelf.h =================================================================== --- contrib/elftoolchain/libelf/gelf.h +++ contrib/elftoolchain/libelf/gelf.h @@ -39,6 +39,7 @@ typedef Elf64_Word GElf_Word; /* Unsigned words (32 bit) */ typedef Elf64_Xword GElf_Xword; /* Unsigned long words (64 bit) */ +typedef Elf64_Chdr GElf_Chdr; /* Compressed section header */ typedef Elf64_Dyn GElf_Dyn; /* ".dynamic" section entries */ typedef Elf64_Ehdr GElf_Ehdr; /* ELF header */ typedef Elf64_Phdr GElf_Phdr; /* Program header */ @@ -73,6 +74,7 @@ long gelf_checksum(Elf *_elf); size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count, unsigned int _version); +GElf_Chdr *gelf_getchdr(Elf_Scn *_scn, GElf_Chdr *_dst); int gelf_getclass(Elf *_elf); GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst); GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst); Index: contrib/elftoolchain/libelf/gelf.3 =================================================================== --- contrib/elftoolchain/libelf/gelf.3 +++ contrib/elftoolchain/libelf/gelf.3 @@ -45,6 +45,8 @@ .Bl -tag -width GElf_Sxword .It Vt GElf_Addr A representation of ELF addresses. +.It Vt GElf_Chdr +A class-independent representation of an ELF Compression Header. .It Vt GElf_Dyn A class-independent representation of ELF .Sy .dynamic @@ -144,6 +146,8 @@ .El .It "Retrieving ELF Data" .Bl -tag -compact -width indent +.It Fn gelf_getchdr +Retrieve an ELF Compression Header from the underlying ELF descriptor. .It Fn gelf_getdyn Retrieve an ELF .Sy .dynamic Index: contrib/elftoolchain/libelf/gelf_chdr.c =================================================================== --- /dev/null +++ contrib/elftoolchain/libelf/gelf_chdr.c @@ -0,0 +1,82 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Tiger Gao under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "_libelf.h" + +Elf32_Chdr * +elf32_getchdr(Elf_Scn *s) +{ + return (_libelf_getchdr(s, ELFCLASS32)); +} + +Elf64_Chdr * +elf64_getchdr(Elf_Scn *s) +{ + return (_libelf_getchdr(s, ELFCLASS64)); +} + +GElf_Chdr * +gelf_getchdr(Elf_Scn *s, GElf_Chdr *d) +{ + int ec; + void *ch; + Elf32_Chdr *ch32; + Elf64_Chdr *ch64; + + if (d == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((ch = _libelf_getchdr(s, ELFCLASSNONE)) == NULL) + return (NULL); + + ec = s->s_elf->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) { + ch32 = (Elf32_Chdr *)ch; + + d->ch_type = (Elf64_Word)ch32->ch_type; + d->ch_size = (Elf64_Xword)ch32->ch_size; + d->ch_addralign = (Elf64_Xword)ch32->ch_addralign; + } else { + ch64 = (Elf64_Chdr *)ch; + *d = *ch64; + } + + return (d); +} Index: contrib/elftoolchain/libelf/gelf_getchdr.3 =================================================================== --- /dev/null +++ contrib/elftoolchain/libelf/gelf_getchdr.3 @@ -0,0 +1,117 @@ +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2020 The FreeBSD Foundation +.\" +.\" This document was written by Tiger Gao under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions are +.\" met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: gelf_getchdr.3 3639 2020-10-20 16:07:02Z tig $ +.\" +.Dd October 20, 2020 +.Dt GELF_GETCHDR 3 +.Os +.Sh NAME +.Nm elf32_getchdr , +.Nm elf64_getchdr , +.Nm gelf_getchdr +.Nd retrieve the compression header of a section +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Chdr *" +.Fn elf32_getchdr "Elf_Scn *s" +.Ft "Elf64_Chdr *" +.Fn elf64_getchdr "Elf_Scn *s" +.In gelf.h +.Ft "GElf_Chdr *" +.Fn gelf_getchdr "Elf_Scn *scn" "GElf_Chdr *chdr" +.Sh DESCRIPTION +These functions return a pointer to the ELF Compression Header data +structure associated with section descriptor +.Ar scn . +.Pp +Function +.Fn elf32_getchdr +retrieves a pointer to an +.Vt Elf32_Chdr +structure. +Section descriptor +.Ar scn +must be associated with an ELF descriptor of class +.Dv ELFCLASS32 . +.Pp +Function +.Fn elf64_getchdr +retrieves a pointer to an +.Vt Elf64_Chdr +structure. +Section descriptor +.Ar scn +must be associated with an ELF descriptor of class +.Dv ELFCLASS64 . +.Pp +Function +.Fn gelf_getchdr +copies the values in the compression header associated with argument +.Ar scn +to the structure pointed to be argument +.Ar dst . +The +.Vt GElf_Chdr +data structure is described in +.Xr gelf 3 . +.Sh RETURN VALUES +Functions +.Fn elf32_getchdr +and +.Fn elf64_getchdr +return a valid pointer to the appropriate compression header on success +or NULL if an error was encountered. +.Pp +Function +.Fn gelf_getchdr +returns argument +.Ar dst +if successful, or NULL if an error was encountered. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_INVALID_SECTION_FLAGS +Arguments +.Ar scn +has invalid flags. +.It Bq Er ELF_E_INVALID_SECTION_TYPE +Argument +.Ar scn +has invalid type. +.It Bq Er ELF_E_NOT_COMPRESSED +Argument +.Ar scn +is not compressed. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , Index: contrib/elftoolchain/libelf/libelf.h =================================================================== --- contrib/elftoolchain/libelf/libelf.h +++ contrib/elftoolchain/libelf/libelf.h @@ -162,6 +162,9 @@ ELF_E_SEQUENCE, /* API calls out of sequence */ ELF_E_UNIMPL, /* Feature is unimplemented */ ELF_E_VERSION, /* Unknown API version */ + ELF_E_INVALID_SECTION_FLAGS, /* Invalid ELF section header flags */ + ELF_E_INVALID_SECTION_TYPE, /* Invalid ELF section header type */ + ELF_E_NOT_COMPRESSED, /* Section is not compressed */ ELF_E_NUM /* Max error number */ }; @@ -227,6 +230,7 @@ long elf32_checksum(Elf *_elf); size_t elf32_fsize(Elf_Type _type, size_t _count, unsigned int _version); +Elf32_Chdr *elf32_getchdr(Elf_Scn *_scn); Elf32_Ehdr *elf32_getehdr(Elf *_elf); Elf32_Phdr *elf32_getphdr(Elf *_elf); Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn); @@ -240,6 +244,7 @@ long elf64_checksum(Elf *_elf); size_t elf64_fsize(Elf_Type _type, size_t _count, unsigned int _version); +Elf64_Chdr *elf64_getchdr(Elf_Scn *_scn); Elf64_Ehdr *elf64_getehdr(Elf *_elf); Elf64_Phdr *elf64_getphdr(Elf *_elf); Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn); Index: contrib/elftoolchain/libelf/libelf_chdr.c =================================================================== --- /dev/null +++ contrib/elftoolchain/libelf/libelf_chdr.c @@ -0,0 +1,104 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Tiger Gao under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "_libelf.h" + +void * +_libelf_getchdr(Elf_Scn *s, int ec) +{ + Elf *e; + void *sh; + Elf32_Shdr *sh32; + Elf64_Shdr *sh64; + + sh32 = NULL; + sh64 = NULL; + + if (s == NULL || (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASSNONE) { + ec = e->e_class; + } else if (ec != e->e_class) { + LIBELF_SET_ERROR(CLASS, 0); + return (NULL); + } + + if ((sh = _libelf_getshdr(s, ec)) == NULL) { + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + sh32 = (Elf32_Shdr *)sh; + if ((sh32->sh_flags & SHF_ALLOC) != 0) { + LIBELF_SET_ERROR(INVALID_SECTION_FLAGS, 0); + return (NULL); + } + + if (sh32->sh_type == SHT_NULL || sh32->sh_type == SHT_NOBITS) { + LIBELF_SET_ERROR(INVALID_SECTION_TYPE, 0); + return (NULL); + } + + if ((sh32->sh_flags & SHF_COMPRESSED) == 0) { + LIBELF_SET_ERROR(NOT_COMPRESSED, 0); + return (NULL); + } + } else { + sh64 = (Elf64_Shdr *)sh; + if ((sh64->sh_flags & SHF_ALLOC) != 0) { + LIBELF_SET_ERROR(INVALID_SECTION_FLAGS, 0); + return (NULL); + } + + if (sh64->sh_type == SHT_NULL || sh64->sh_type == SHT_NOBITS) { + LIBELF_SET_ERROR(INVALID_SECTION_TYPE, 0); + return (NULL); + } + + if ((sh64->sh_flags & SHF_COMPRESSED) == 0) { + LIBELF_SET_ERROR(NOT_COMPRESSED, 0); + return (NULL); + } + } + + Elf_Data *d = elf_getdata(s, NULL); + + if (!d) + return (NULL); + + return ((void *)d->d_buf); +} Index: lib/libelf/Makefile =================================================================== --- lib/libelf/Makefile +++ lib/libelf/Makefile @@ -38,6 +38,7 @@ elf_update.c \ elf_version.c \ gelf_cap.c \ + gelf_chdr.c \ gelf_checksum.c \ gelf_dyn.c \ gelf_ehdr.c \ @@ -57,6 +58,7 @@ libelf_allocate.c \ libelf_ar.c \ libelf_ar_util.c \ + libelf_chdr.c \ libelf_checksum.c \ libelf_data.c \ libelf_ehdr.c \