Re: [PATCH dwarves 1/3] dwarf_loader: Refactor function parameter__new()

Alan Maguire
2024-11-11T11:27:16Z

On 08/11/2024 18:05, Yonghong Song wrote:
> The dwarf location checking part of function parameter__new() is refactored
> to another function. The current dwarf location checking only for
> the first expression of the first location. One later patch may traverse
> all expressions of all locations, so refactoring makes later change easier.
>
> No functional change.
>
> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> ---
> dwarf_loader.c | 77 ++++++++++++++++++++++++++++----------------------
> 1 file changed, 44 insertions(+), 33 deletions(-)
>
> diff --git a/dwarf_loader.c b/dwarf_loader.c
> index ec8641b..4bb9096 100644
> --- a/dwarf_loader.c
> +++ b/dwarf_loader.c
> @@ -1157,16 +1157,56 @@ static struct template_parameter_pack *template_parameter_pack__new(Dwarf_Die *d
> return pack;
> }
>
> +static bool check_dwarf_locations(Dwarf_Attribute *attr, struct parameter *parm,
> + struct cu *cu, int param_idx)

Nit: I think this should be renamed to something like
parameter__locations() in keeping with existing naming scheme.
Could also include the parm->has_loc assignment there instead
of keeping it in paramter__new().

> +{
> + Dwarf_Addr base, start, end;
> + struct location loc;
> +
> + /* dwarf_getlocations() handles location lists; here we are
> + * only interested in the first expr.
> + */
> + if (parm->has_loc &&
> +#if _ELFUTILS_PREREQ(0, 157)
> + dwarf_getlocations(attr, 0, &base, &start, &end,
> + &loc.expr, &loc.exprlen) > 0 &&
> +#else
> + dwarf_getlocation(attr, &loc.expr, &loc.exprlen) == 0 &&
> +#endif
> + loc.exprlen != 0) {
> + int expected_reg = cu->register_params[param_idx];
> + Dwarf_Op *expr = loc.expr;
> +
> + switch (expr->atom) {
> + case DW_OP_reg0 ... DW_OP_reg31:
> + /* mark parameters that use an unexpected
> + * register to hold a parameter; these will
> + * be problematic for users of BTF as they
> + * violate expectations about register
> + * contents.
> + */
> + if (expected_reg >= 0 && expected_reg != expr->atom)
> + parm->unexpected_reg = 1;
> + break;
> + default:
> + parm->optimized = 1;
> + break;
> + }
> +
> + return true;
> + }
> +
> + return false;
> +}
> +
> static struct parameter *parameter__new(Dwarf_Die *die, struct cu *cu,
> struct conf_load *conf, int param_idx)
> {
> struct parameter *parm = tag__alloc(cu, sizeof(*parm));
>
> if (parm != NULL) {
> - Dwarf_Addr base, start, end;
> bool has_const_value;
> Dwarf_Attribute attr;
> - struct location loc;
>
> tag__init(&parm->tag, cu, die);
> parm->name = attr_string(die, DW_AT_name, conf);
> @@ -1208,38 +1248,9 @@ static struct parameter *parameter__new(Dwarf_Die *die, struct cu *cu,
> */
> has_const_value = dwarf_attr(die, DW_AT_const_value, &attr) != NULL;
> parm->has_loc = dwarf_attr(die, DW_AT_location, &attr) != NULL;
> - /* dwarf_getlocations() handles location lists; here we are
> - * only interested in the first expr.
> - */
> - if (parm->has_loc &&
> -#if _ELFUTILS_PREREQ(0, 157)
> - dwarf_getlocations(&attr, 0, &base, &start, &end,
> - &loc.expr, &loc.exprlen) > 0 &&
> -#else
> - dwarf_getlocation(&attr, &loc.expr, &loc.exprlen) == 0 &&
> -#endif
> - loc.exprlen != 0) {
> - int expected_reg = cu->register_params[param_idx];
> - Dwarf_Op *expr = loc.expr;
> -
> - switch (expr->atom) {
> - case DW_OP_reg0 ... DW_OP_reg31:
> - /* mark parameters that use an unexpected
> - * register to hold a parameter; these will
> - * be problematic for users of BTF as they
> - * violate expectations about register
> - * contents.
> - */
> - if (expected_reg >= 0 && expected_reg != expr->atom)
> - parm->unexpected_reg = 1;
> - break;
> - default:
> - parm->optimized = 1;
> - break;
> - }
> - } else if (has_const_value) {
> +
> + if (!check_dwarf_locations(&attr, parm, cu, param_idx) && has_const_value)

I think it might be easier to follow the logic if we moved the const
check alongside the location checks in the separate location check
function. That way all our optimization-related checking happens in one
place.

> parm->optimized = 1;
> - }
> }
>
> return parm;