[PATCH pahole] btf_encoder: preserve and encode exported functions as BTF_KIND_FUNC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add encoding of DWARF's DW_TAG_subprogram_type into BTF's BTF_KIND_FUNC
(plus corresponding BTF_KIND_FUNC_PROTO). Only exported functions are
converted for now. This allows to capture all the exported kernel functions,
same subset that's exposed through /proc/kallsyms.

Acked-by: Alexei Starovoitov <ast@xxxxxxxxxx>
Tested-by: Alexei Starovoitov <ast@xxxxxxxxxx>
Signed-off-by: Andrii Nakryiko <andriin@xxxxxx>
---
 btf_encoder.c  | 16 ++++++++++++++++
 dwarf_loader.c |  1 +
 dwarves.h      |  1 +
 3 files changed, 18 insertions(+)

diff --git a/btf_encoder.c b/btf_encoder.c
index f85b978a3981..df16ba0ae98e 100644
--- a/btf_encoder.c
+++ b/btf_encoder.c
@@ -173,6 +173,7 @@ int cu__encode_btf(struct cu *cu, int verbose)
 	bool add_index_type = false;
 	uint32_t type_id_off;
 	uint32_t core_id;
+	struct function *fn;
 	struct tag *pos;
 	int err = 0;
 
@@ -225,6 +226,21 @@ int cu__encode_btf(struct cu *cu, int verbose)
 		btf_elf__add_base_type(btfe, &bt);
 	}
 
+	cu__for_each_function(cu, core_id, fn) {
+		int btf_fnproto_id, btf_fn_id;
+
+		if (fn->declaration || !fn->external)
+			continue;
+
+		btf_fnproto_id = btf_elf__add_func_proto(btfe, &fn->proto, type_id_off);
+		btf_fn_id = btf_elf__add_ref_type(btfe, BTF_KIND_FUNC, btf_fnproto_id, fn->name, false);
+		if (btf_fnproto_id < 0 || btf_fn_id < 0) {
+			err = -1;
+			printf("error: failed to encode function '%s'\n", function__name(fn, cu));
+			goto out;
+		}
+	}
+
 out:
 	if (err)
 		btf_elf__delete(btfe);
diff --git a/dwarf_loader.c b/dwarf_loader.c
index 4c6783b9af7e..09edcfb91bf0 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -920,6 +920,7 @@ static struct function *function__new(Dwarf_Die *die, struct cu *cu)
 		func->name	      = strings__add(strings, attr_string(die, DW_AT_name));
 		func->linkage_name    = strings__add(strings, attr_string(die, DW_AT_MIPS_linkage_name));
 		func->inlined	      = attr_numeric(die, DW_AT_inline);
+		func->declaration     = dwarf_hasattr(die, DW_AT_declaration);
 		func->external	      = dwarf_hasattr(die, DW_AT_external);
 		func->abstract_origin = dwarf_hasattr(die, DW_AT_abstract_origin);
 		dwarf_tag__set_spec(func->proto.tag.priv,
diff --git a/dwarves.h b/dwarves.h
index b162e751cc99..b53bdfc2bca9 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -784,6 +784,7 @@ struct function {
 	uint8_t		 external:1;
 	uint8_t		 accessibility:2; /* DW_ACCESS_{public,protected,private} */
 	uint8_t		 virtuality:2; /* DW_VIRTUALITY_{none,virtual,pure_virtual} */
+	uint8_t		 declaration:1;
 	int32_t		 vtable_entry;
 	struct list_head vtable_node;
 	/* fields used by tools */
-- 
2.17.1




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux