Handle static and external linkage for BTF subprograms (functions). Signed-off-by: Will Hawkins <hawkinsw@xxxxxx> --- btf_loader.c | 4 +++- dwarves.h | 2 +- pfunct.c | 15 ++++++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/btf_loader.c b/btf_loader.c index e0d029a..16962f9 100644 --- a/btf_loader.c +++ b/btf_loader.c @@ -85,8 +85,10 @@ static int create_new_function(struct cu *cu, const struct btf_type *tp, uint32_ return -ENOMEM; // for BTF this is not really the type of the return of the function, - // but the prototype, the return type is the one in type_id + // but the prototype, the return type is the one in type_id. func->btf = 1; + func->declaration = BTF_INFO_VLEN(tp->info) == BTF_FUNC_EXTERN; + func->external = BTF_INFO_VLEN(tp->info) == BTF_FUNC_GLOBAL; func->proto.tag.tag = DW_TAG_subprogram; func->proto.tag.type = tp->type; func->name = cu__btf_str(cu, tp->name_off); diff --git a/dwarves.h b/dwarves.h index f5ae79f..c6d2b63 100644 --- a/dwarves.h +++ b/dwarves.h @@ -983,7 +983,7 @@ struct function { uint16_t cu_total_nr_inline_expansions; uint8_t inlined:2; uint8_t abstract_origin:1; - uint8_t external:1; + uint8_t external:1; /* DW_AT_external */ uint8_t accessibility:2; /* DW_ACCESS_{public,protected,private} */ uint8_t virtuality:2; /* DW_VIRTUALITY_{none,virtual,pure_virtual} */ uint8_t declaration:1; diff --git a/pfunct.c b/pfunct.c index 938dd72..725cc2e 100644 --- a/pfunct.c +++ b/pfunct.c @@ -366,9 +366,22 @@ static void function__show(struct function *func, struct cu *cu) { struct tag *tag = function__tag(func); - if (func->abstract_origin || func->external) + if (func->abstract_origin) return; + // If this function is more than a declaration, then be + // explicit about its linkage. For dwarf, external comes + // from DW_AT_external which, when combined with whether + // the DIE represents a defined subprogram, determines + // the linkage. BTF maintains these semantics when it reads + // type information. + if (!func->declaration) { + if (func->external) + fprintf(stdout, "extern "); + else + fprintf(stdout, "static "); + } + if (expand_types) function__emit_type_definitions(func, cu, stdout); tag__fprintf(tag, cu, &conf, stdout); -- 2.45.2