From nobody Thu Jan 18 22:26:31 2024 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 4TGHQw2CGVz578fk; Thu, 18 Jan 2024 22:26:32 +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 4TGHQv5X31z42Nh; Thu, 18 Jan 2024 22:26:31 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705616791; 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=feOx0YwkzWFtHaT8AegMFhmD05pGK/T3AioKE/CSKk4=; b=QDzpTjNYGlJZPhvP6Zu3w8pQQVxcbgezlPo6KZT6GYM2EGT026GH8wbl9F15nENBggTw+L 08I+nwQJ3sFLo2Km/pDrRAHQc98KI38Wb1Ds/xTXcoNlRIU+qDDWXmv0DNVrnuqXAcY5aV 4HbIsPPn/NJPbWjdms3sUmNRt/xkZtbhh6RInl98irOPdeEczL2W8MVXsbNcy5wMURl30C i7PMBdnHlHiVyrc4ZsxRxTCI4PGj8DW+sL7wIODR4eUUGJDvRntLhOcggbWc3mfvZa5ojH 2TM0KpBsFXLyIy2ev+fYAfgfA5oegPQ6qg3/MiC3jurmLiHN7pBoPOnehFAJIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705616791; 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=feOx0YwkzWFtHaT8AegMFhmD05pGK/T3AioKE/CSKk4=; b=XfP4Cd9fi0j7ja2yrrWbdfUzuqwRDbiWUbdvra8dz+U6ZqD0jJxq3POFR/vji9D0G+47J7 5VIHTqL7wkD5DlMlat/YA/7L6rNBPCBHUCKutHMa31VY/jUFsn83+sy0+JpXXkBOmf2Nol 7gDGlHlxdF35ZSHAtaSRJacm+t1PraJAPiXKiIop9z9AVat9XQyiezXS541zV04nvD2XHk T9GSaP9PwHTskfBp+KMvXbbKyvoIAvqRkfxm85Ibzaeys20Lrb0xKTenPyvAIIwA5r9r5m VXwtQjkmc43g10DwcwlG/3foS5KEZ0O+7UKT/35KGgLRaSf0RRjGjvqyahgq1A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1705616791; a=rsa-sha256; cv=none; b=PEbYdaLMFLoVzqfVUvrbi0q6SPtLQgkYo+W8eOTDNCBjJeU69HUnAfJTUucDj01tAOJI3J LDQhe3veEO0Vr006B/LYU9/6W1dXhlnSuX7hguysEElLjvTAbLzNxcsyTkPOlmIi8wlpmY v3nAoMk+Jr126BrMDowu/BeQmTfpfOq6F70ShkC8Rn3EbuSzBZPXoX3sFzaOtjDTFsMOE/ s0TpDQdxrX0RSQClDjwviiR8AqiyQkUgqHMy1Q9JBeV/1aXXoBjyLBU6JSLq33XVdd72nu 1zXNcDBWvYtT9i0fvWMKmCXDUxNl2wT1fQ0Xpv0e7JixTN3lO133QJ4qSpJ11w== 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 4TGHQv4f1bzPyr; Thu, 18 Jan 2024 22:26:31 +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 40IMQVxW090608; Thu, 18 Jan 2024 22:26:31 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 40IMQVRA090605; Thu, 18 Jan 2024 22:26:31 GMT (envelope-from git) Date: Thu, 18 Jan 2024 22:26:31 GMT Message-Id: <202401182226.40IMQVRA090605@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: John Baldwin Subject: git: 21dec6c48f08 - stable/13 - kldxref: Simplify handling of ELF object files 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: jhb X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 21dec6c48f089ce55ec32fa04a8962ea52b3d9ef Auto-Submitted: auto-generated The branch stable/13 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=21dec6c48f089ce55ec32fa04a8962ea52b3d9ef commit 21dec6c48f089ce55ec32fa04a8962ea52b3d9ef Author: John Baldwin AuthorDate: 2023-12-22 15:49:18 +0000 Commit: John Baldwin CommitDate: 2024-01-18 21:31:32 +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 (cherry picked from commit 0d557cdf6f0e94e909acea065f3de2a28437ae74) --- 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) {