From 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Thu, 16 May 2024 03:11:33 +0000 Subject: [PATCH] AX88772C_eeprom and ax8872c build together --- kernel/tools/perf/util/dwarf-aux.c | 134 ++++++++++++++++++++++++++++++-------------- 1 files changed, 91 insertions(+), 43 deletions(-) diff --git a/kernel/tools/perf/util/dwarf-aux.c b/kernel/tools/perf/util/dwarf-aux.c index 230e94b..443374a 100644 --- a/kernel/tools/perf/util/dwarf-aux.c +++ b/kernel/tools/perf/util/dwarf-aux.c @@ -1,28 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * dwarf-aux.c : libdw auxiliary interfaces - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * */ #include <errno.h> #include <inttypes.h> #include <stdbool.h> -#include "util.h" +#include <stdlib.h> #include "debug.h" #include "dwarf-aux.h" +#include "strbuf.h" #include "string2.h" /** @@ -72,6 +59,51 @@ return dwarf_formstring(&attr); } +/* Unlike dwarf_getsrc_die(), cu_getsrc_die() only returns statement line */ +static Dwarf_Line *cu_getsrc_die(Dwarf_Die *cu_die, Dwarf_Addr addr) +{ + Dwarf_Addr laddr; + Dwarf_Lines *lines; + Dwarf_Line *line; + size_t nlines, l, u, n; + bool flag; + + if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0 || + nlines == 0) + return NULL; + + /* Lines are sorted by address, use binary search */ + l = 0; u = nlines - 1; + while (l < u) { + n = u - (u - l) / 2; + line = dwarf_onesrcline(lines, n); + if (!line || dwarf_lineaddr(line, &laddr) != 0) + return NULL; + if (addr < laddr) + u = n - 1; + else + l = n; + } + /* Going backward to find the lowest line */ + do { + line = dwarf_onesrcline(lines, --l); + if (!line || dwarf_lineaddr(line, &laddr) != 0) + return NULL; + } while (laddr == addr); + l++; + /* Going foward to find the statement line */ + do { + line = dwarf_onesrcline(lines, l++); + if (!line || dwarf_lineaddr(line, &laddr) != 0 || + dwarf_linebeginstatement(line, &flag) != 0) + return NULL; + if (laddr > addr) + return NULL; + } while (!flag); + + return line; +} + /** * cu_find_lineinfo - Get a line number and file name for given address * @cu_die: a CU DIE @@ -85,17 +117,26 @@ const char **fname, int *lineno) { Dwarf_Line *line; - Dwarf_Addr laddr; + Dwarf_Die die_mem; + Dwarf_Addr faddr; - line = dwarf_getsrc_die(cu_die, (Dwarf_Addr)addr); - if (line && dwarf_lineaddr(line, &laddr) == 0 && - addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) { + if (die_find_realfunc(cu_die, (Dwarf_Addr)addr, &die_mem) + && die_entrypc(&die_mem, &faddr) == 0 && + faddr == addr) { + *fname = dwarf_decl_file(&die_mem); + dwarf_decl_line(&die_mem, lineno); + goto out; + } + + line = cu_getsrc_die(cu_die, (Dwarf_Addr)addr); + if (line && dwarf_lineno(line, lineno) == 0) { *fname = dwarf_linesrc(line, NULL, NULL); if (!*fname) /* line number is useless without filename */ *lineno = 0; } +out: return *lineno ?: -ENOENT; } @@ -267,21 +308,8 @@ { Dwarf_Attribute attr; - if (dwarf_attr(tp_die, attr_name, &attr) == NULL || + if (dwarf_attr_integrate(tp_die, attr_name, &attr) == NULL || dwarf_formudata(&attr, result) != 0) - return -ENOENT; - - return 0; -} - -/* Get attribute and translate it as a sdata */ -static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name, - Dwarf_Sword *result) -{ - Dwarf_Attribute attr; - - if (dwarf_attr(tp_die, attr_name, &attr) == NULL || - dwarf_formsdata(&attr, result) != 0) return -ENOENT; return 0; @@ -315,9 +343,25 @@ bool die_is_func_def(Dwarf_Die *dw_die) { Dwarf_Attribute attr; + Dwarf_Addr addr = 0; - return (dwarf_tag(dw_die) == DW_TAG_subprogram && - dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL); + if (dwarf_tag(dw_die) != DW_TAG_subprogram) + return false; + + if (dwarf_attr(dw_die, DW_AT_declaration, &attr)) + return false; + + /* + * DW_AT_declaration can be lost from function declaration + * by gcc's bug #97060. + * So we need to check this subprogram DIE has DW_AT_inline + * or an entry address. + */ + if (!dwarf_attr(dw_die, DW_AT_inline, &attr) && + die_entrypc(dw_die, &addr) < 0) + return false; + + return true; } /** @@ -410,9 +454,9 @@ /* Get the call file index number in CU DIE */ static int die_get_call_fileno(Dwarf_Die *in_die) { - Dwarf_Sword idx; + Dwarf_Word idx; - if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0) + if (die_get_attr_udata(in_die, DW_AT_call_file, &idx) == 0) return (int)idx; else return -ENOENT; @@ -421,9 +465,9 @@ /* Get the declared file index number in CU DIE */ static int die_get_decl_fileno(Dwarf_Die *pdie) { - Dwarf_Sword idx; + Dwarf_Word idx; - if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0) + if (die_get_attr_udata(pdie, DW_AT_decl_file, &idx) == 0) return (int)idx; else return -ENOENT; @@ -918,9 +962,13 @@ if ((tag == DW_TAG_formal_parameter || tag == DW_TAG_variable) && die_compare_name(die_mem, fvp->name) && - /* Does the DIE have location information or external instance? */ + /* + * Does the DIE have location information or const value + * or external instance? + */ (dwarf_attr(die_mem, DW_AT_external, &attr) || - dwarf_attr(die_mem, DW_AT_location, &attr))) + dwarf_attr(die_mem, DW_AT_location, &attr) || + dwarf_attr(die_mem, DW_AT_const_value, &attr))) return DIE_FIND_CB_END; if (dwarf_haspc(die_mem, fvp->addr)) return DIE_FIND_CB_CONTINUE; @@ -1033,7 +1081,7 @@ ret = die_get_typename(vr_die, buf); if (ret < 0) { pr_debug("Failed to get type, make it unknown.\n"); - ret = strbuf_add(buf, " (unknown_type)", 14); + ret = strbuf_add(buf, "(unknown_type)", 14); } return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); -- Gitblit v1.6.2