From nobody Mon Dec 06 16:21:46 2021 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 52D0918B098F; Mon, 6 Dec 2021 16:21:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4J77wq0MMbz4t7c; Mon, 6 Dec 2021 16:21:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E0E0A6EA5; Mon, 6 Dec 2021 16:21:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1B6GLk5M070819; Mon, 6 Dec 2021 16:21:46 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1B6GLkla070818; Mon, 6 Dec 2021 16:21:46 GMT (envelope-from git) Date: Mon, 6 Dec 2021 16:21:46 GMT Message-Id: <202112061621.1B6GLkla070818@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: dbf05458e3bd - main - libdwarf: Support consumption of compressed ELF sections List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: dbf05458e3bd8c46f5e49918593557293a29d41a Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1638807707; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XSKkawn8nE5mK72rtA7TSTv+EertMyEivCya0G0SE/k=; b=giRZ0SnnxV3LXn2h1oHG0G+NBZ/xa9q9SRFoOSAsAExez+50GXs+EaskZTsLiu/UyH6XEG hwC9ui5N9kgDDLWFDgVswkmnwquQMgThfDdqyntZZTQvQl3igUMyEfzDS9L2UcaqcFxLaE RFloNH77TaPJbfcsSN5Y9txicBZDP8qY6V29MB2AeDp/chl6pRjA3OG+KcgSt0vJt/NOP4 Mi5NcMFfP1Bk1Mlsk/KPfKAdD9lx3kIgNMaEZtJGXn99z5EH+T/Z03TQ1ZrAn0PwbPtBD/ koahnp/vUyeGaxUN3WcNhb9AuBcH5tJRXHrNSZbX2CuwB859C8rx+7fsWzN/gQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1638807707; a=rsa-sha256; cv=none; b=OAVTlDGV/vcC+3xofAJogfJ7pzSRWHbXtCPg9xCaoBkEAevRAxTOra1fbQsdFmWTIQbgXj KDYNs+6btzhUUm2Rl88yt0GICYPC/dM1mj0R9qj6HJVX1ZQNrxRSWZ8lrGXCqpPJiW/uKL CVkEdoWz6hbus9PRzH7py2dxW63+uk9D9sQvFprpSNjSbq10xujDjfAgIR9CElRG2mOR83 atGTtS420a728nyJUsxmsEvNmqRrK7yJA9uOiywVgL3wSmx1oHHqWltpoBNnT/4KbtZvgw Eg6eB8xYe4mtJL2HzOyvoP+0X9vOvRo+0kSoJRsano8XuGs7TfB9xDSjynhJMA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=dbf05458e3bd8c46f5e49918593557293a29d41a commit dbf05458e3bd8c46f5e49918593557293a29d41a Author: Mark Johnston AuthorDate: 2021-12-06 15:37:49 +0000 Commit: Mark Johnston CommitDate: 2021-12-06 15:37:49 +0000 libdwarf: Support consumption of compressed ELF sections Automatically decompress zlib-compressed debug sections when loading them. This lets ctfcovert work on userland code after commit c910570e7573 ("Use compressed debug in standalone userland debug files by default"). Reported by: avg Reviewed by: avg, emaste MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D33139 --- contrib/elftoolchain/libdwarf/_libdwarf.h | 5 +- contrib/elftoolchain/libdwarf/libdwarf.h | 1 + contrib/elftoolchain/libdwarf/libdwarf_elf_init.c | 87 +++++++++++++++++++---- lib/libdwarf/Makefile | 2 +- share/mk/src.libnames.mk | 2 +- 5 files changed, 80 insertions(+), 17 deletions(-) diff --git a/contrib/elftoolchain/libdwarf/_libdwarf.h b/contrib/elftoolchain/libdwarf/_libdwarf.h index 6658d2d2f6f4..68a4c61522fa 100644 --- a/contrib/elftoolchain/libdwarf/_libdwarf.h +++ b/contrib/elftoolchain/libdwarf/_libdwarf.h @@ -379,8 +379,9 @@ typedef struct _Dwarf_Rel_Section { } *Dwarf_Rel_Section; typedef struct { - Elf_Data *ed_data; - void *ed_alloc; + Elf_Data *ed_data; + void *ed_alloc; + size_t ed_size; /* Uncompressed size. */ } Dwarf_Elf_Data; typedef struct { diff --git a/contrib/elftoolchain/libdwarf/libdwarf.h b/contrib/elftoolchain/libdwarf/libdwarf.h index 6ec8f99c56a1..b1f9e0c8abc7 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf.h +++ b/contrib/elftoolchain/libdwarf/libdwarf.h @@ -335,6 +335,7 @@ enum { DW_DLE_ARANGE_OFFSET_BAD, /* Invalid arange offset. */ DW_DLE_DEBUG_MACRO_INCONSISTENT,/* Invalid macinfo data. */ DW_DLE_ELF_SECT_ERR, /* Application callback failed. */ + DW_DLE_COMPRESSION, /* Section decompression error. */ DW_DLE_NUM /* Max error number. */ }; diff --git a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c index e304ef164157..c9b6ae601e0e 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c @@ -25,6 +25,7 @@ */ #include "_libdwarf.h" +#include ELFTC_VCSID("$Id: libdwarf_elf_init.c 3475 2016-05-18 18:11:26Z emaste $"); @@ -168,21 +169,28 @@ _dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx, return (DW_DLE_NONE); } - ed->ed_alloc = malloc(ed->ed_data->d_size); + /* + * A copy may already have been created if the section + * is compressed. + */ if (ed->ed_alloc == NULL) { - DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); - return (DW_DLE_MEMORY); + ed->ed_alloc = malloc(ed->ed_size); + if (ed->ed_alloc == NULL) { + DWARF_SET_ERROR(dbg, error, + DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + memcpy(ed->ed_alloc, ed->ed_data->d_buf, + ed->ed_size); } - memcpy(ed->ed_alloc, ed->ed_data->d_buf, - ed->ed_data->d_size); if (sh.sh_type == SHT_REL) _dwarf_elf_apply_rel_reloc(dbg, - ed->ed_alloc, ed->ed_data->d_size, + ed->ed_alloc, ed->ed_size, rel, symtab_data, eh.e_ident[EI_DATA]); else _dwarf_elf_apply_rela_reloc(dbg, - ed->ed_alloc, ed->ed_data->d_size, - rel, symtab_data, eh.e_ident[EI_DATA]); + ed->ed_alloc, ed->ed_size, rel, symtab_data, + eh.e_ident[EI_DATA]); return (DW_DLE_NONE); } @@ -196,13 +204,58 @@ _dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx, return (DW_DLE_NONE); } +static int +_dwarf_elf_decompress(Dwarf_Debug dbg, Dwarf_Elf_Object *e, Elf_Scn *scn, + Dwarf_Elf_Data *ed, GElf_Shdr *shdr, Dwarf_Error *error) +{ + GElf_Chdr chdr; + size_t hsize; + unsigned long csize; + + if (gelf_getchdr(scn, &chdr) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + return (DW_DLE_ELF); + } + + if (chdr.ch_type != ELFCOMPRESS_ZLIB) { + DWARF_SET_ERROR(dbg, error, DW_DLE_COMPRESSION); + return (DW_DLE_COMPRESSION); + } + + if ((ed->ed_alloc = malloc(chdr.ch_size)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + csize = chdr.ch_size; + hsize = e->eo_ehdr.e_ident[EI_CLASS] == ELFCLASS64 ? + sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr); + if (uncompress(ed->ed_alloc, &csize, (char *)ed->ed_data->d_buf + hsize, + ed->ed_data->d_size - hsize) != Z_OK) { + DWARF_SET_ERROR(dbg, error, DW_DLE_COMPRESSION); + return (DW_DLE_COMPRESSION); + } + /* Sanity check. */ + if (csize != chdr.ch_size) { + DWARF_SET_ERROR(dbg, error, DW_DLE_COMPRESSION); + return (DW_DLE_COMPRESSION); + } + + ed->ed_size = chdr.ch_size; + shdr->sh_size = chdr.ch_size; + shdr->sh_addralign = chdr.ch_addralign; + + return (DW_DLE_NONE); +} + int _dwarf_elf_init(Dwarf_Debug dbg, Elf *elf, Dwarf_Error *error) { Dwarf_Obj_Access_Interface *iface; + Dwarf_Elf_Data *ed; Dwarf_Elf_Object *e; const char *name; - GElf_Shdr sh; + GElf_Shdr *es, sh; Elf_Scn *scn; Elf_Data *symtab_data; size_t symtab_ndx; @@ -319,8 +372,6 @@ _dwarf_elf_init(Dwarf_Debug dbg, Elf *elf, Dwarf_Error *error) if (sh.sh_type == SHT_NOBITS) continue; - memcpy(&e->eo_shdr[j], &sh, sizeof(sh)); - if ((name = elf_strptr(elf, e->eo_strndx, sh.sh_name)) == NULL) { DWARF_SET_ELF_ERROR(dbg, error); @@ -328,13 +379,15 @@ _dwarf_elf_init(Dwarf_Debug dbg, Elf *elf, Dwarf_Error *error) goto fail_cleanup; } + ed = &e->eo_data[j]; + es = &e->eo_shdr[j]; + memcpy(es, &sh, sizeof(sh)); for (i = 0; debug_name[i] != NULL; i++) { if (strcmp(name, debug_name[i])) continue; (void) elf_errno(); - if ((e->eo_data[j].ed_data = elf_getdata(scn, NULL)) == - NULL) { + if ((ed->ed_data = elf_getdata(scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) { _DWARF_SET_ERROR(dbg, error, @@ -344,6 +397,14 @@ _dwarf_elf_init(Dwarf_Debug dbg, Elf *elf, Dwarf_Error *error) } } + if ((sh.sh_flags & SHF_COMPRESSED) != 0) { + if (_dwarf_elf_decompress(dbg, e, scn, ed, + es, error) != DW_DLE_NONE) + goto fail_cleanup; + } else { + ed->ed_size = ed->ed_data->d_size; + } + if (_libdwarf.applyreloc) { if (_dwarf_elf_relocate(dbg, elf, &e->eo_data[j], elf_ndxscn(scn), symtab_ndx, diff --git a/lib/libdwarf/Makefile b/lib/libdwarf/Makefile index 03f40cdd85ee..a3ef95b2572a 100644 --- a/lib/libdwarf/Makefile +++ b/lib/libdwarf/Makefile @@ -98,7 +98,7 @@ sys/elf32.h sys/elf64.h sys/elf_common.h: ${SRCTOP}/sys/${.TARGET} .NOMETA mkdir -p ${.OBJDIR}/sys ln -sf ${.ALLSRC} ${.TARGET} -LIBADD+= elf +LIBADD+= elf z SHLIB_MAJOR= 4 diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index bc3ad9c4bf40..23d09a434466 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -329,7 +329,7 @@ _DP_fetch= ssl crypto _DP_fetch= md .endif _DP_execinfo= elf -_DP_dwarf= elf +_DP_dwarf= elf z _DP_dpv= dialog figpar util tinfow ncursesw _DP_dialog= tinfow ncursesw m _DP_cuse= pthread