From nobody Fri Dec 22 15:50:12 2023 X-Original-To: dev-commits-src-main@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 4SxWw514vNz547Pm; Fri, 22 Dec 2023 15:50:13 +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 4SxWw45s2Kz3R50; Fri, 22 Dec 2023 15:50:12 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1703260212; 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=Mq2tc9To86IgvOsHsGGIX7+oA/ELiVwjx1KKkcVomkE=; b=RaLdAzqYX6te+/t/OnUlg18Cs6CokVeUsEOGXJeTj6Wz06K9MmwZFnr6VBOPeuzkKZLbbt H4D4FH9nPTewsuQHcYJg5aTOE8nhXQSAnGckEGFtCQ+WgH38B89UM8G7nrMlGnnbylnk4U snYBzhTFARCvUZJkrZ5YUOR2IOKFKuxmPgVqfpDOprna24hOCZHrMcKfplsYAxNbcdByTn oJcWUmtnHtExRVSew8d65hpwSLV/vwbqg0Vom8/FR1qstA/tC5GT0/AUJOTsGkCgTO4Q9/ 1PjL9XK4Sg4LSdLsga8fK2ZqB+RX9LL+voioPU78xqXdR05NmIy1rJBT7HA0Qw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1703260212; a=rsa-sha256; cv=none; b=HRq0JJiA9/sRypLgTvrQSy9Tv0k/YymjXwGJqHUGmGF1YoLo3kHoAipeATkXycskA1Yxxk EBnk5ngxczMlan1qgI7fezvvzerR8OUnA1hP4BH4Wzxe0e0FOAb0XjqgoGmhYQ2AYR23Y1 6P6WTzbE99Tc46Cc45tNCPYjkL67NVe4b2paIDqXsk5I7N4l84nPRK7Ry9gSX7JYBXqBm5 fYtTEWnfgQPXhgNsgqeA8QVi6FydGGOz0HamFMK+VifqNpAE0HgBbjFzsIJQ27HeYtE351 7XMmU35EnFBhcSE/2tyz1ix3unJh3VGaWSgEhtKTJHuw/UoCyp41kSI2YQFCUg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1703260212; 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=Mq2tc9To86IgvOsHsGGIX7+oA/ELiVwjx1KKkcVomkE=; b=sKACRwjEYOXHMNKbUzz4X1y/aXhY+CM97WAh2/NQwMJqPJDnagdNqIlLF3Am5SXUqtQb0A pK6GNNCDEaAcVs9FOD3oDVyIlHIK21+VdAK4eXMpvuzH9V/osQTgVtAiqWIZQIXLdRcdCl kSSlFhn2OCNY8f8sXiRlIo0zirKxS6/PdE9hw7VZs9xQ84a/IsXfGuzu5zGJeefJTvZ5kH oB5XvTrKrWpxf+oDmedzOiS8NiUY355cuNJa2jsyDrTeh8++AiHWCEzzMKVfdzlRdi1wyG u/h+eHU9iB5Zd7xx9UCq+YzI0A6vXPGpdJ/wQ+Y0wX/LF/vcenAmRmesiSmuBg== 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 4SxWw44mMwz75Q; Fri, 22 Dec 2023 15:50:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3BMFoC14099940; Fri, 22 Dec 2023 15:50:12 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3BMFoC2k099935; Fri, 22 Dec 2023 15:50:12 GMT (envelope-from git) Date: Fri, 22 Dec 2023 15:50:12 GMT Message-Id: <202312221550.3BMFoC2k099935@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: 0d557cdf6f0e - main - kldxref: Simplify handling of ELF object files List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 0d557cdf6f0e94e909acea065f3de2a28437ae74 Auto-Submitted: auto-generated The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=0d557cdf6f0e94e909acea065f3de2a28437ae74 commit 0d557cdf6f0e94e909acea065f3de2a28437ae74 Author: John Baldwin AuthorDate: 2023-12-22 15:49:18 +0000 Commit: John Baldwin CommitDate: 2023-12-22 15:49:18 +0000 kldxref: Simplify handling of ELF object files Unlike the backend for ELF DSOs, the object file backend allocated an aligned chunk of memory and read all of the in-memory sections from the file into this memory even though most of the file contents were never used. Instead, just track a set of virtual addresses (based at 0) that each loaded section would be loaded at and only read the necessary bits from the backing file when needed. Reviewed by: imp Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D43126 --- usr.sbin/kldxref/ef_obj.c | 146 +++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 81 deletions(-) diff --git a/usr.sbin/kldxref/ef_obj.c b/usr.sbin/kldxref/ef_obj.c index 36c0dce432b6..1274a14c10af 100644 --- a/usr.sbin/kldxref/ef_obj.c +++ b/usr.sbin/kldxref/ef_obj.c @@ -46,7 +46,8 @@ #include "ef.h" typedef struct { - char *addr; + GElf_Addr addr; + GElf_Off offset; GElf_Off size; int flags; int sec; /* Original section */ @@ -69,9 +70,6 @@ struct ef_file { char *ef_name; struct elf_file *ef_efile; - char *address; - GElf_Off size; - Elf_progent *progtab; int nprogtab; @@ -113,6 +111,22 @@ static struct elf_file_ops ef_obj_file_ops = { .lookup_set = ef_obj_lookup_set, }; +static GElf_Off +ef_obj_get_offset(elf_file_t ef, GElf_Addr addr) +{ + Elf_progent *pt; + int i; + + for (i = 0; i < ef->nprogtab; i++) { + pt = &ef->progtab[i]; + if (pt->offset == (GElf_Off)-1) + continue; + if (addr >= pt->addr && addr < pt->addr + pt->size) + return (pt->offset + (addr - pt->addr)); + } + return (0); +} + static int ef_obj_lookup_symbol(elf_file_t ef, const char *name, GElf_Sym **sym) { @@ -139,9 +153,8 @@ ef_obj_lookup_set(elf_file_t ef, const char *name, GElf_Addr *startp, for (i = 0; i < ef->nprogtab; i++) { if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) && strcmp(ef->progtab[i].name + 4, name) == 0) { - *startp = ef->progtab[i].addr - ef->address; - *stopp = ef->progtab[i].addr + ef->progtab[i].size - - ef->address; + *startp = ef->progtab[i].addr; + *stopp = ef->progtab[i].addr + ef->progtab[i].size; *countp = (*stopp - *startp) / elf_pointer_size(ef->ef_efile); return (0); @@ -160,46 +173,50 @@ ef_obj_symaddr(elf_file_t ef, GElf_Size symidx) sym = ef->ddbsymtab + symidx; if (sym->st_shndx != SHN_UNDEF) - return (sym->st_value - (GElf_Addr)ef->address); + return (sym->st_value); return (0); } static int ef_obj_seg_read_rel(elf_file_t ef, GElf_Addr address, size_t len, void *dest) { - char *memaddr; + GElf_Off secofs; GElf_Rel *r; GElf_Rela *a; GElf_Addr secbase, dataoff; int error, i, sec; - if (address + len > ef->size) { - if (ef->ef_verbose) - warnx("ef_obj_seg_read_rel(%s): bad offset/len (%lx:%ld)", - ef->ef_name, (long)address, (long)len); - return (EFAULT); - } - bcopy(ef->address + address, dest, len); - /* Find out which section contains the data. */ - memaddr = ef->address + address; sec = -1; - secbase = dataoff = 0; for (i = 0; i < ef->nprogtab; i++) { - if (ef->progtab[i].addr == NULL) + if (address < ef->progtab[i].addr) continue; - if (memaddr < (char *)ef->progtab[i].addr || memaddr + len > - (char *)ef->progtab[i].addr + ef->progtab[i].size) + + dataoff = address - ef->progtab[i].addr; + if (dataoff + len > ef->progtab[i].size) continue; + sec = ef->progtab[i].sec; - /* We relocate to address 0. */ - secbase = (char *)ef->progtab[i].addr - ef->address; - dataoff = memaddr - ef->address; + secbase = ef->progtab[i].addr; + secofs = ef->progtab[i].offset; break; } - if (sec == -1) + if (sec == -1) { + if (ef->ef_verbose) + warnx("ef_obj_seg_read_rel(%s): bad address (%jx)", + ef->ef_name, (uintmax_t)address); return (EFAULT); + } + + if (secofs == (GElf_Off)-1) { + memset(dest, 0, len); + } else { + error = elf_read_raw_data(ef->ef_efile, secofs + dataoff, dest, + len); + if (error != 0) + return (error); + } /* Now do the relocations. */ for (i = 0; i < ef->nrel; i++) { @@ -208,7 +225,7 @@ ef_obj_seg_read_rel(elf_file_t ef, GElf_Addr address, size_t len, void *dest) for (r = ef->reltab[i].rel; r < &ef->reltab[i].rel[ef->reltab[i].nrel]; r++) { error = elf_reloc(ef->ef_efile, r, ELF_T_REL, secbase, - dataoff, len, dest); + address, len, dest); if (error != 0) return (error); } @@ -219,7 +236,7 @@ ef_obj_seg_read_rel(elf_file_t ef, GElf_Addr address, size_t len, void *dest) for (a = ef->relatab[i].rela; a < &ef->relatab[i].rela[ef->relatab[i].nrela]; a++) { error = elf_reloc(ef->ef_efile, a, ELF_T_RELA, secbase, - dataoff, len, dest); + address, len, dest); if (error != 0) return (error); } @@ -230,21 +247,23 @@ ef_obj_seg_read_rel(elf_file_t ef, GElf_Addr address, size_t len, void *dest) static int ef_obj_seg_read_string(elf_file_t ef, GElf_Addr address, size_t len, char *dest) { + GElf_Off ofs; + int error; - if (address >= ef->size) { + ofs = ef_obj_get_offset(ef, address); + if (ofs == 0) { if (ef->ef_verbose) - warnx("ef_obj_seg_read_string(%s): bad address (%lx)", - ef->ef_name, (long)address); + warnx("ef_obj_seg_read_string(%s): bad address (%jx)", + ef->ef_name, (uintmax_t)address); return (EFAULT); } - if (ef->size - address < len) - len = ef->size - address; - - if (strnlen(ef->address + address, len) == len) + error = elf_read_raw_data(ef->ef_efile, ofs, dest, len); + if (error != 0) + return (error); + if (strnlen(dest, len) == len) return (EFAULT); - memcpy(dest, ef->address + address, len); return (0); } @@ -255,8 +274,8 @@ ef_obj_open(struct elf_file *efile, int verbose) GElf_Ehdr *hdr; GElf_Shdr *shdr; GElf_Sym *es; - char *mapbase; - size_t i, mapsize, alignmask, max_addralign, nshdr; + GElf_Addr mapbase; + size_t i, nshdr; int error, pb, ra, rl; int j, nsym, symstrindex, symtabindex; @@ -359,59 +378,26 @@ ef_obj_open(struct elf_file *efile, int verbose) } } - /* Size up code/data(progbits) and bss(nobits). */ - alignmask = 0; - max_addralign = 0; - mapsize = 0; - for (i = 0; i < nshdr; i++) { - switch (shdr[i].sh_type) { - case SHT_PROGBITS: - case SHT_NOBITS: - alignmask = shdr[i].sh_addralign - 1; - if (shdr[i].sh_addralign > max_addralign) - max_addralign = shdr[i].sh_addralign; - mapsize += alignmask; - mapsize &= ~alignmask; - mapsize += shdr[i].sh_size; - break; - } - } - - /* We know how much space we need for the text/data/bss/etc. */ - ef->size = mapsize; - if (posix_memalign((void **)&ef->address, max_addralign, mapsize)) { - printf("posix_memalign failed\n"); - goto out; - } - mapbase = ef->address; - /* - * Now load code/data(progbits), zero bss(nobits), allocate - * space for and load relocs + * Now allocate address space for code/data(progbits) and + * bss(nobits) and allocate space for and load relocs. */ pb = 0; rl = 0; ra = 0; - alignmask = 0; + mapbase = 0; for (i = 0; i < nshdr; i++) { switch (shdr[i].sh_type) { case SHT_PROGBITS: case SHT_NOBITS: - alignmask = shdr[i].sh_addralign - 1; - mapbase += alignmask; - mapbase = (char *)((uintptr_t)mapbase & ~alignmask); - ef->progtab[pb].addr = (void *)(uintptr_t)mapbase; + mapbase = roundup2(mapbase, shdr[i].sh_addralign); + ef->progtab[pb].addr = mapbase; if (shdr[i].sh_type == SHT_PROGBITS) { ef->progtab[pb].name = "<>"; - if (elf_read_raw_data(efile, - shdr[i].sh_offset, ef->progtab[pb].addr, - shdr[i].sh_size) != 0) { - printf("failed to read progbits\n"); - goto out; - } + ef->progtab[pb].offset = shdr[i].sh_offset; } else { ef->progtab[pb].name = "<>"; - bzero(ef->progtab[pb].addr, shdr[i].sh_size); + ef->progtab[pb].offset = (GElf_Off)-1; } ef->progtab[pb].size = shdr[i].sh_size; ef->progtab[pb].sec = i; @@ -424,7 +410,7 @@ ef_obj_open(struct elf_file *efile, int verbose) es = &ef->ddbsymtab[j]; if (es->st_shndx != i) continue; - es->st_value += (GElf_Addr)ef->progtab[pb].addr; + es->st_value += ef->progtab[pb].addr; } mapbase += shdr[i].sh_size; pb++; @@ -464,8 +450,6 @@ ef_obj_close(elf_file_t ef) if (ef->ef_name) free(ef->ef_name); - if (ef->size != 0) - free(ef->address); if (ef->nprogtab != 0) free(ef->progtab); if (ef->nrel != 0) {