From nobody Tue Dec 16 12:38:43 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EEDAD29825C; Fri, 9 May 2025 20:18:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821891; cv=none; b=sXxkBCazxZyiwukVWo52ms1xBNjS7XF8VmXZ6AtNmMCtrlW2bMJ4UMnZV3+Sy2wv4NxOgnVczFYUfYy42gJ4byY8TwzATUfXxrIGmyuM2Puk5oRsqljUILCuQXt2ZJzaV0IYZ1aG3cvsl4nmYyCtBkvQ07qh2zOfAoBTHnhQNnw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821891; c=relaxed/simple; bh=7swKUK/3k6EQBq1Fv6U9z1jYwUKygY8A2CCrfaG+2Ic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TntNwG+EXjD+soIML9bfEbJoUZIwi+CqU/trKEWGBsum6fE/mYC/8AQsh4Sif2QslWfg23MwVKJwrB5FcOefKyH4GK5ZTRggq8+P9A2JQMbb8pJTabgUfkg0L6V5ziS4gYPhTtNpDEsni/b32TlBhDhVGJ8apVwiP1BCZRkc4o4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GKQnQ267; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GKQnQ267" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 51CE8C4CEEF; Fri, 9 May 2025 20:18:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821890; bh=7swKUK/3k6EQBq1Fv6U9z1jYwUKygY8A2CCrfaG+2Ic=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GKQnQ267ruruAesKwORHho6uxAxcSXM8yFFdLWo9zsckgONLLkH5J7J7bXrrxPpX3 t+3iVQpG81jB7F+sfxAa5NJGUansJsxi4nG0Zmxo7dIFn8g9yh68Y21n+4YBj/SYSm dy9wtn22Ng5Hj4JeOcppvotCQ36YpLRLmQsJrSGsWuJ/6Drt9QuXe9Mlcl4aMu5LOu RxlGgtC63h31ndJyo0snoows7C4VfBWnai/DmLxDgR/fmTjYcp+WpxgGHYZXOwGn5v DrgrLe1KEBpNCpWPoHxrqbdpNvZiDQr+XVuE4eDPZtGIB38K9WatHAgHF9Vg4AZqgX Un+Snc+SFW7AA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 37/62] objtool: Generalize elf_create_symbol() Date: Fri, 9 May 2025 13:17:01 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, broaden the elf_create_symbol() interface to give callers more control and reduce duplication of some subtle setup logic. While at it, make elf_create_symbol() and elf_create_section_symbol() public so sections can be created by the upcoming klp diff code. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 111 +++++++++++++++------------- tools/objtool/include/objtool/elf.h | 11 ++- 2 files changed, 69 insertions(+), 53 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 859d677e172c..38bf9ae86c89 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -761,24 +761,60 @@ static int elf_update_symbol(struct elf *elf, struct = section *symtab, return 0; } =20 -static struct symbol * -__elf_create_symbol(struct elf *elf, struct symbol *sym) +static int elf_add_string(struct elf *elf, struct section *strtab, const c= har *str); + +struct symbol *elf_create_symbol(struct elf *elf, const char *name, + struct section *sec, unsigned int bind, + unsigned int type, unsigned long offset, + size_t size) { struct section *symtab, *symtab_shndx; Elf32_Word first_non_local, new_idx; - struct symbol *old; + struct symbol *old, *sym; + + sym =3D calloc(1, sizeof(*sym)); + if (!sym) { + ERROR_GLIBC("calloc"); + return NULL; + } + + sym->name =3D strdup(name); + if (!sym->name) { + ERROR_GLIBC("strdup"); + return NULL; + } + + if (type !=3D STT_SECTION) { + sym->sym.st_name =3D elf_add_string(elf, NULL, sym->name); + if (sym->sym.st_name =3D=3D -1) + return NULL; + } + + if (sec) { + sym->sec =3D sec; + } else { + sym->sec =3D find_section_by_index(elf, 0); + if (!sym->sec) { + ERROR("no NULL section"); + return NULL; + } + } + + sym->sym.st_info =3D GELF_ST_INFO(bind, type); + sym->sym.st_value =3D offset; + sym->sym.st_size =3D size; =20 symtab =3D find_section_by_name(elf, ".symtab"); - if (symtab) { - symtab_shndx =3D find_section_by_name(elf, ".symtab_shndx"); - } else { + if (!symtab) { ERROR("no .symtab"); return NULL; } =20 + symtab_shndx =3D find_section_by_name(elf, ".symtab_shndx"); + new_idx =3D sec_num_entries(symtab); =20 - if (GELF_ST_BIND(sym->sym.st_info) !=3D STB_LOCAL) + if (bind !=3D STB_LOCAL) goto non_local; =20 /* @@ -816,10 +852,8 @@ __elf_create_symbol(struct elf *elf, struct symbol *sy= m) =20 non_local: sym->idx =3D new_idx; - if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) { - ERROR("elf_update_symbol"); + if (sym->idx && elf_update_symbol(elf, symtab, symtab_shndx, sym)) return NULL; - } =20 symtab->sh.sh_size +=3D symtab->sh.sh_entsize; mark_sec_changed(elf, symtab, true); @@ -829,64 +863,39 @@ __elf_create_symbol(struct elf *elf, struct symbol *s= ym) mark_sec_changed(elf, symtab_shndx, true); } =20 + elf_add_symbol(elf, sym); + return sym; } =20 -static struct symbol * -elf_create_section_symbol(struct elf *elf, struct section *sec) +struct symbol *elf_create_section_symbol(struct elf *elf, struct section *= sec) { struct symbol *sym =3D calloc(1, sizeof(*sym)); =20 - if (!sym) { - ERROR_GLIBC("malloc"); + sym =3D elf_create_symbol(elf, sec->name, sec, STB_LOCAL, STT_SECTION, 0,= 0); + if (!sym) return NULL; - } =20 - sym->name =3D sec->name; - sym->sec =3D sec; - - // st_name 0 - sym->sym.st_info =3D GELF_ST_INFO(STB_LOCAL, STT_SECTION); - // st_other 0 - // st_value 0 - // st_size 0 - - sym =3D __elf_create_symbol(elf, sym); - if (sym) - elf_add_symbol(elf, sym); + sec->sym =3D sym; =20 return sym; } =20 -static int elf_add_string(struct elf *elf, struct section *strtab, const c= har *str); - struct symbol * -elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size) +elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, size_t size) { - struct symbol *sym =3D calloc(1, sizeof(*sym)); size_t namelen =3D strlen(orig->name) + sizeof("__pfx_"); - char *name =3D malloc(namelen); - - if (!sym || !name) { - ERROR_GLIBC("malloc"); - return NULL; - } + char name[SYM_NAME_LEN]; + unsigned long offset; =20 snprintf(name, namelen, "__pfx_%s", orig->name); =20 - sym->name =3D name; - sym->sec =3D orig->sec; + offset =3D orig->sym.st_value - size; =20 - sym->sym.st_name =3D elf_add_string(elf, NULL, name); - sym->sym.st_info =3D orig->sym.st_info; - sym->sym.st_value =3D orig->sym.st_value - size; - sym->sym.st_size =3D size; - - sym =3D __elf_create_symbol(elf, sym); - if (sym) - elf_add_symbol(elf, sym); - - return sym; + return elf_create_symbol(elf, name, orig->sec, + GELF_ST_BIND(orig->sym.st_info), + GELF_ST_TYPE(orig->sym.st_info), + offset, size); } =20 static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, @@ -932,7 +941,7 @@ struct reloc *elf_init_reloc_text_sym(struct elf *elf, = struct section *sec, unsigned long insn_off) { struct symbol *sym =3D insn_sec->sym; - int addend =3D insn_off; + s64 addend =3D insn_off; =20 if (!is_text_sec(insn_sec)) { ERROR("bad call to %s() for data symbol %s", __func__, sym->name); @@ -949,8 +958,6 @@ struct reloc *elf_init_reloc_text_sym(struct elf *elf, = struct section *sec, sym =3D elf_create_section_symbol(elf, insn_sec); if (!sym) return NULL; - - insn_sec->sym =3D sym; } =20 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 74c7b84b5310..ffdf9ec3882e 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -15,6 +15,8 @@ #include #include =20 +#define SYM_NAME_LEN 512 + #ifdef LIBELF_USE_DEPRECATED # define elf_getshdrnum elf_getshnum # define elf_getshdrstrndx elf_getshstrndx @@ -119,7 +121,14 @@ struct section *elf_create_section_pair(struct elf *el= f, const char *name, size_t entsize, unsigned int nr, unsigned int reloc_nr); =20 -struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *or= ig, long size); +struct symbol *elf_create_symbol(struct elf *elf, const char *name, + struct section *sec, unsigned int bind, + unsigned int type, unsigned long offset, + size_t size); +struct symbol *elf_create_section_symbol(struct elf *elf, struct section *= sec); +struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *or= ig, + size_t size); + =20 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, unsigned long offset, --=20 2.49.0