diff --git a/dwarves.changes b/dwarves.changes index 682fb38..de938c5 100644 --- a/dwarves.changes +++ b/dwarves.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon May 3 08:45:43 UTC 2021 - Jiri Slaby + +- add remove-ftrace-filter.patch + ------------------------------------------------------------------- Thu Apr 22 10:25:46 UTC 2021 - Jan Engelhardt diff --git a/dwarves.spec b/dwarves.spec index daff10c..0fb245d 100644 --- a/dwarves.spec +++ b/dwarves.spec @@ -28,6 +28,7 @@ URL: http://acmel.wordpress.com/ Source: https://fedorapeople.org/~acme/dwarves/dwarves-%version.tar.xz Source2: https://fedorapeople.org/~acme/dwarves/dwarves-%version.tar.sign Source9: baselibs.conf +Patch0: remove-ftrace-filter.patch BuildRequires: cmake BuildRequires: libdw-devel >= 0.171 %if 0%{?suse_version} < 1550 diff --git a/remove-ftrace-filter.patch b/remove-ftrace-filter.patch new file mode 100644 index 0000000..28aa283 --- /dev/null +++ b/remove-ftrace-filter.patch @@ -0,0 +1,343 @@ +From: Jiri Slaby +Date: Tue, 4 May 2021 08:09:50 +0200 +Subject: remove ftrace filter +Patch-mainline: under discussion +References: ppc64 kernel build failure + +Functions in the .opd section on ppc64 are currently ignored as they +don't contain mcount calls -- they are excluded by the ftrace filter. +Therefore, pahole cannot produce a .BTF section from vmlinux and kernel +build fails on ppc64. + +Remove the ftrace filter completely as was discussed: + https://lore.kernel.org/bpf/20210501001653.x3b4rk4vk4iqv3n7@kafai-mbp.dhcp.thefacebook.com/ + https://lore.kernel.org/bpf/YI%2FLgjLxo9VCN%2Fd+@krava/ + +Signed-off-by: Jiri Slaby +--- + btf_encoder.c | 272 +------------------------------------------------- + 1 file changed, 5 insertions(+), 267 deletions(-) + +diff --git a/btf_encoder.c b/btf_encoder.c +index 80e896961d4e..ba83bb088efa 100644 +--- a/btf_encoder.c ++++ b/btf_encoder.c +@@ -27,17 +27,8 @@ + */ + #define KSYM_NAME_LEN 128 + +-struct funcs_layout { +- unsigned long mcount_start; +- unsigned long mcount_stop; +- unsigned long mcount_sec_idx; +-}; +- + struct elf_function { + const char *name; +- unsigned long addr; +- unsigned long size; +- unsigned long sh_addr; + bool generated; + }; + +@@ -98,250 +89,11 @@ static int collect_function(struct btf_elf *btfe, GElf_Sym *sym, + } + + functions[functions_cnt].name = name; +- functions[functions_cnt].addr = elf_sym__value(sym); +- functions[functions_cnt].size = elf_sym__size(sym); +- functions[functions_cnt].sh_addr = sh.sh_addr; + functions[functions_cnt].generated = false; + functions_cnt++; + return 0; + } + +-static int addrs_cmp(const void *_a, const void *_b) +-{ +- const __u64 *a = _a; +- const __u64 *b = _b; +- +- if (*a == *b) +- return 0; +- return *a < *b ? -1 : 1; +-} +- +-static int get_vmlinux_addrs(struct btf_elf *btfe, struct funcs_layout *fl, +- __u64 **paddrs, __u64 *pcount) +-{ +- __u64 *addrs, count, offset; +- unsigned int addr_size, i; +- Elf_Data *data; +- GElf_Shdr shdr; +- Elf_Scn *sec; +- +- /* Initialize for the sake of all error paths below. */ +- *paddrs = NULL; +- *pcount = 0; +- +- if (!fl->mcount_start || !fl->mcount_stop) +- return 0; +- +- /* +- * Find mcount addressed marked by __start_mcount_loc +- * and __stop_mcount_loc symbols and load them into +- * sorted array. +- */ +- sec = elf_getscn(btfe->elf, fl->mcount_sec_idx); +- if (!sec || !gelf_getshdr(sec, &shdr)) { +- fprintf(stderr, "Failed to get section(%lu) header.\n", +- fl->mcount_sec_idx); +- return -1; +- } +- +- /* Get address size from processed file's ELF class. */ +- addr_size = gelf_getclass(btfe->elf) == ELFCLASS32 ? 4 : 8; +- +- offset = fl->mcount_start - shdr.sh_addr; +- count = (fl->mcount_stop - fl->mcount_start) / addr_size; +- +- data = elf_getdata(sec, 0); +- if (!data) { +- fprintf(stderr, "Failed to get section(%lu) data.\n", +- fl->mcount_sec_idx); +- return -1; +- } +- +- addrs = malloc(count * sizeof(addrs[0])); +- if (!addrs) { +- fprintf(stderr, "Failed to allocate memory for ftrace addresses.\n"); +- return -1; +- } +- +- if (addr_size == sizeof(__u64)) { +- memcpy(addrs, data->d_buf + offset, count * addr_size); +- } else { +- for (i = 0; i < count; i++) +- addrs[i] = (__u64) *((__u32 *) (data->d_buf + offset + i * addr_size)); +- } +- +- *paddrs = addrs; +- *pcount = count; +- return 0; +-} +- +-static int +-get_kmod_addrs(struct btf_elf *btfe, __u64 **paddrs, __u64 *pcount) +-{ +- __u64 *addrs, count; +- unsigned int addr_size, i; +- GElf_Shdr shdr_mcount; +- Elf_Data *data; +- Elf_Scn *sec; +- +- /* Initialize for the sake of all error paths below. */ +- *paddrs = NULL; +- *pcount = 0; +- +- /* get __mcount_loc */ +- sec = elf_section_by_name(btfe->elf, &btfe->ehdr, &shdr_mcount, +- "__mcount_loc", NULL); +- if (!sec) { +- if (btf_elf__verbose) { +- printf("%s: '%s' doesn't have __mcount_loc section\n", __func__, +- btfe->filename); +- } +- return 0; +- } +- +- data = elf_getdata(sec, NULL); +- if (!data) { +- fprintf(stderr, "Failed to data for __mcount_loc section.\n"); +- return -1; +- } +- +- /* Get address size from processed file's ELF class. */ +- addr_size = gelf_getclass(btfe->elf) == ELFCLASS32 ? 4 : 8; +- +- count = data->d_size / addr_size; +- +- addrs = malloc(count * sizeof(addrs[0])); +- if (!addrs) { +- fprintf(stderr, "Failed to allocate memory for ftrace addresses.\n"); +- return -1; +- } +- +- if (addr_size == sizeof(__u64)) { +- memcpy(addrs, data->d_buf, count * addr_size); +- } else { +- for (i = 0; i < count; i++) +- addrs[i] = (__u64) *((__u32 *) (data->d_buf + i * addr_size)); +- } +- +- /* +- * We get Elf object from dwfl_module_getelf function, +- * which performs all possible relocations, including +- * __mcount_loc section. +- * +- * So addrs array now contains relocated values, which +- * we need take into account when we compare them to +- * functions values, see comment in setup_functions +- * function. +- */ +- *paddrs = addrs; +- *pcount = count; +- return 0; +-} +- +-static int is_ftrace_func(struct elf_function *func, __u64 *addrs, __u64 count) +-{ +- __u64 start = func->addr; +- __u64 addr, end = func->addr + func->size; +- +- /* +- * The invariant here is addr[r] that is the smallest address +- * that is >= than function start addr. Except the corner case +- * where there is no such r, but for that we have a final check +- * in the return. +- */ +- size_t l = 0, r = count - 1, m; +- +- /* make sure we don't use invalid r */ +- if (count == 0) +- return false; +- +- while (l < r) { +- m = l + (r - l) / 2; +- addr = addrs[m]; +- +- if (addr >= start) { +- /* we satisfy invariant, so tighten r */ +- r = m; +- } else { +- /* m is not good enough as l, maybe m + 1 will be */ +- l = m + 1; +- } +- } +- +- return start <= addrs[r] && addrs[r] < end; +-} +- +-static int setup_functions(struct btf_elf *btfe, struct funcs_layout *fl) +-{ +- __u64 *addrs, count, i; +- int functions_valid = 0; +- bool kmod = false; +- +- /* +- * Check if we are processing vmlinux image and +- * get mcount data if it's detected. +- */ +- if (get_vmlinux_addrs(btfe, fl, &addrs, &count)) +- return -1; +- +- /* +- * Check if we are processing kernel module and +- * get mcount data if it's detected. +- */ +- if (!addrs) { +- if (get_kmod_addrs(btfe, &addrs, &count)) +- return -1; +- kmod = true; +- } +- +- if (!addrs) { +- if (btf_elf__verbose) +- printf("ftrace symbols not detected, falling back to DWARF data\n"); +- delete_functions(); +- return 0; +- } +- +- qsort(addrs, count, sizeof(addrs[0]), addrs_cmp); +- qsort(functions, functions_cnt, sizeof(functions[0]), functions_cmp); +- +- /* +- * Let's got through all collected functions and filter +- * out those that are not in ftrace. +- */ +- for (i = 0; i < functions_cnt; i++) { +- struct elf_function *func = &functions[i]; +- /* +- * For vmlinux image both addrs[x] and functions[x]::addr +- * values are final address and are comparable. +- * +- * For kernel module addrs[x] is final address, but +- * functions[x]::addr is relative address within section +- * and needs to be relocated by adding sh_addr. +- */ +- if (kmod) +- func->addr += func->sh_addr; +- +- /* Make sure function is within ftrace addresses. */ +- if (is_ftrace_func(func, addrs, count)) { +- /* +- * We iterate over sorted array, so we can easily skip +- * not valid item and move following valid field into +- * its place, and still keep the 'new' array sorted. +- */ +- if (i != functions_valid) +- functions[functions_valid] = functions[i]; +- functions_valid++; +- } +- } +- +- functions_cnt = functions_valid; +- free(addrs); +- +- if (btf_elf__verbose) +- printf("Found %d functions!\n", functions_cnt); +- return 0; +-} +- + static struct elf_function *find_function(const struct btf_elf *btfe, + const char *name) + { +@@ -620,23 +372,8 @@ static int collect_percpu_var(struct btf_elf *btfe, GElf_Sym *sym, + return 0; + } + +-static void collect_symbol(GElf_Sym *sym, struct funcs_layout *fl, +- size_t sym_sec_idx) +-{ +- if (!fl->mcount_start && +- !strcmp("__start_mcount_loc", elf_sym__name(sym, btfe->symtab))) { +- fl->mcount_start = sym->st_value; +- fl->mcount_sec_idx = sym_sec_idx; +- } +- +- if (!fl->mcount_stop && +- !strcmp("__stop_mcount_loc", elf_sym__name(sym, btfe->symtab))) +- fl->mcount_stop = sym->st_value; +-} +- + static int collect_symbols(struct btf_elf *btfe, bool collect_percpu_vars) + { +- struct funcs_layout fl = { }; + Elf32_Word sym_sec_idx; + uint32_t core_id; + GElf_Sym sym; +@@ -650,7 +387,6 @@ static int collect_symbols(struct btf_elf *btfe, bool collect_percpu_vars) + return -1; + if (collect_function(btfe, &sym, sym_sec_idx)) + return -1; +- collect_symbol(&sym, &fl, sym_sec_idx); + } + + if (collect_percpu_vars) { +@@ -661,9 +397,11 @@ static int collect_symbols(struct btf_elf *btfe, bool collect_percpu_vars) + printf("Found %d per-CPU variables!\n", percpu_var_cnt); + } + +- if (functions_cnt && setup_functions(btfe, &fl)) { +- fprintf(stderr, "Failed to filter DWARF functions\n"); +- return -1; ++ if (functions_cnt) { ++ qsort(functions, functions_cnt, sizeof(functions[0]), functions_cmp); ++ ++ if (btf_elf__verbose) ++ printf("Found %d functions!\n", functions_cnt); + } + + return 0; +-- +2.31.1 +