From patchwork Thu Jan 9 19:00:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ihor Solodrai X-Patchwork-Id: 13933145 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-10628.protonmail.ch (mail-10628.protonmail.ch [79.135.106.28]) (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 0C3921FECB4; Thu, 9 Jan 2025 19:00:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.28 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736449228; cv=none; b=RGbiNlAmKtTKxfYxhmYXIoR/ZlO+nj/AiZHxC84DCsyk8xzgBlUDCKKBI8tIEHOFhKu82EQtZxduYStX0+JmlQxQWBdX/PeG8+i++9eGOWKV297Oa5lS0WBp22W5ZyLYBkFkn+wLMDs5hs/2E++m4c6EBomj8y6FRf+K0VmDa1k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736449228; c=relaxed/simple; bh=o3xJm1jPieeFN7ryRV63B6sNoCeL8Wgg+cSLWOa3llY=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TxT5kOLAD7aRR7+h7P+IISJzgQkMRutIDFnAMoQg0LxSjmh1POFT9qqj22CgYC3sLN0OvO1kthTKZUABZnaLREsXLD2zkw5NHw0e+4TzKJcWkpfl5gu/p13Ct1WVg63wAitNplOpsqgS1a0DS0Q27stWyv5mfQcOIJbyJl70tIQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=JL7AGAVD; arc=none smtp.client-ip=79.135.106.28 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="JL7AGAVD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1736449219; x=1736708419; bh=8mBD+M0m7V8hE8vUw41Vafqwv7TCJHqc8TffLy10gt4=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=JL7AGAVDiRNa35himMnzIu2kVA2JLjNqeUcHKRKAgcREKzsGWPFiYMSsc/YJW8vUY JPlqQhF1zMJfxqqsv54ZTgnBeHXntXDJvfseQfyuH5MV+NS7sPGBR5AsqQkJnXxbrR YXF5cWNStRIccpiyJSQPdUQJ9V1ugGkkaNqbuj1mx1uymdwf0folDcXxlkS3VD9Tld mE7P2+q2o76AP4ebwxiFlY/u2zT1SEGEQJrQuvftXC14AOuFqp7/p66q8WiqMVut67 cRCIjFd1YVkFHufg7CysaUTh5lD3yNBpP8EzWBLXOY4TQeu0WFZtkg7Wt0E3dQfQdC RQwEo/koYgDCA== Date: Thu, 09 Jan 2025 19:00:16 +0000 To: dwarves@vger.kernel.org From: Ihor Solodrai Cc: bpf@vger.kernel.org, acme@kernel.org, alan.maguire@oracle.com, eddyz87@gmail.com, andrii@kernel.org, mykolal@fb.com, olsajiri@gmail.com Subject: [PATCH dwarves v4 RESEND 04/10] btf_encoder: introduce elf_functions struct type Message-ID: <20250109185950.653110-5-ihor.solodrai@pm.me> In-Reply-To: <20250109185950.653110-1-ihor.solodrai@pm.me> References: <20250109185950.653110-1-ihor.solodrai@pm.me> Feedback-ID: 27520582:user:proton X-Pm-Message-ID: fefc21fc765a43973923e141d37624f42331c607 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Extract elf_functions struct type from btf_encoder. Replace routines operating on functions table in btf_encoder by routines operating on elf_functions: - btf_encoder__collect_function -> elf_functions__collect_function - btf_encoder__collect_symbols -> elf_functions__collect Now these functions do not depend on btf_encoder being passed to them as a parameter. Link: https://lore.kernel.org/dwarves/3MqWfdjBO9srtpr8kjweJgCkdwYKV6JC_-SN27S8Y9_J1SzssIgZs4Ptc5tEqpZ7w2vbSmTQ35J5CX35Yb4KMbw8wsTrB2IAf2SWU-k4Xi4=@pm.me/ Link: https://lore.kernel.org/dwarves/20241128012341.4081072-6-ihor.solodrai@pm.me/ Acked-by: Eduard Zingerman Signed-off-by: Ihor Solodrai --- btf_encoder.c | 118 ++++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index 46f224c..1c27700 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -101,6 +101,13 @@ struct elf_secinfo { struct gobuffer secinfo; }; +struct elf_functions { + struct elf_symtab *symtab; + struct elf_function *entries; + int cnt; + int suffix_cnt; /* number of .isra, .part etc */ +}; + /* * cu: cu being processed. */ @@ -127,12 +134,7 @@ struct btf_encoder { size_t seccnt; int encode_vars; struct list_head func_states; - struct { - struct elf_function *entries; - int allocated; - int cnt; - int suffix_cnt; /* number of .isra, .part etc */ - } functions; + struct elf_functions functions; }; struct btf_func { @@ -1210,16 +1212,6 @@ static int functions_cmp(const void *_a, const void *_b) #define max(x, y) ((x) < (y) ? (y) : (x)) #endif -static void *reallocarray_grow(void *ptr, int *nmemb, size_t size) -{ - int new_nmemb = max(1000, *nmemb * 3 / 2); - void *new = realloc(ptr, new_nmemb * size); - - if (new) - *nmemb = new_nmemb; - return new; -} - static int saved_functions_cmp(const void *_a, const void *_b) { struct btf_encoder_func_state * const *a = _a; @@ -1330,44 +1322,30 @@ out: return err; } -static int btf_encoder__collect_function(struct btf_encoder *encoder, GElf_Sym *sym) +static void elf_functions__collect_function(struct elf_functions *functions, GElf_Sym *sym) { - struct elf_function *new; + struct elf_function *func; const char *name; if (elf_sym__type(sym) != STT_FUNC) - return 0; - name = elf_sym__name(sym, encoder->symtab); - if (!name) - return 0; + return; - if (encoder->functions.cnt == encoder->functions.allocated) { - new = reallocarray_grow(encoder->functions.entries, - &encoder->functions.allocated, - sizeof(*encoder->functions.entries)); - if (!new) { - /* - * The cleanup - delete_functions is called - * in btf_encoder__encode_cu error path. - */ - return -1; - } - encoder->functions.entries = new; - } + name = elf_sym__name(sym, functions->symtab); + if (!name) + return; - memset(&encoder->functions.entries[encoder->functions.cnt], 0, - sizeof(*new)); - encoder->functions.entries[encoder->functions.cnt].name = name; + func = &functions->entries[functions->cnt]; + func->name = name; if (strchr(name, '.')) { const char *suffix = strchr(name, '.'); - encoder->functions.suffix_cnt++; - encoder->functions.entries[encoder->functions.cnt].prefixlen = suffix - name; + functions->suffix_cnt++; + func->prefixlen = suffix - name; } else { - encoder->functions.entries[encoder->functions.cnt].prefixlen = strlen(name); + func->prefixlen = strlen(name); } - encoder->functions.cnt++; - return 0; + + functions->cnt++; } static struct elf_function *btf_encoder__find_function(const struct btf_encoder *encoder, @@ -2133,26 +2111,53 @@ int btf_encoder__encode(struct btf_encoder *encoder) return err; } - -static int btf_encoder__collect_symbols(struct btf_encoder *encoder) +static int elf_functions__collect(struct elf_functions *functions) { - uint32_t sym_sec_idx; + uint32_t nr_symbols = elf_symtab__nr_symbols(functions->symtab); + struct elf_function *tmp; + Elf32_Word sym_sec_idx; uint32_t core_id; GElf_Sym sym; + int err = 0; - elf_symtab__for_each_symbol_index(encoder->symtab, core_id, sym, sym_sec_idx) { - if (btf_encoder__collect_function(encoder, &sym)) - return -1; + /* We know that number of functions is less than number of symbols, + * so we can overallocate temporarily. + */ + functions->entries = calloc(nr_symbols, sizeof(*functions->entries)); + if (!functions->entries) { + err = -ENOMEM; + goto out_free; } - if (encoder->functions.cnt) { - qsort(encoder->functions.entries, encoder->functions.cnt, sizeof(encoder->functions.entries[0]), - functions_cmp); - if (encoder->verbose) - printf("Found %d functions!\n", encoder->functions.cnt); + functions->cnt = 0; + elf_symtab__for_each_symbol_index(functions->symtab, core_id, sym, sym_sec_idx) { + elf_functions__collect_function(functions, &sym); + } + + if (functions->cnt) { + qsort(functions->entries, functions->cnt, sizeof(*functions->entries), functions_cmp); + } else { + err = 0; + goto out_free; + } + + /* Reallocate to the exact size */ + tmp = realloc(functions->entries, functions->cnt * sizeof(struct elf_function)); + if (tmp) { + functions->entries = tmp; + } else { + fprintf(stderr, "could not reallocate memory for elf_functions table\n"); + err = -ENOMEM; + goto out_free; } return 0; + +out_free: + free(functions->entries); + functions->entries = NULL; + functions->cnt = 0; + return err; } static bool ftype__has_arg_names(const struct ftype *ftype) @@ -2413,6 +2418,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam printf("%s: '%s' doesn't have symtab.\n", __func__, cu->filename); goto out; } + encoder->functions.symtab = encoder->symtab; /* index the ELF sections for later lookup */ @@ -2451,7 +2457,7 @@ struct btf_encoder *btf_encoder__new(struct cu *cu, const char *detached_filenam if (!found_percpu && encoder->verbose) printf("%s: '%s' doesn't have '%s' section\n", __func__, cu->filename, PERCPU_SECTION); - if (btf_encoder__collect_symbols(encoder)) + if (elf_functions__collect(&encoder->functions)) goto out_delete; if (encoder->verbose) @@ -2483,7 +2489,7 @@ void btf_encoder__delete(struct btf_encoder *encoder) encoder->btf = NULL; elf_symtab__delete(encoder->symtab); - encoder->functions.allocated = encoder->functions.cnt = 0; + encoder->functions.cnt = 0; free(encoder->functions.entries); encoder->functions.entries = NULL;