On 8/15/24 19:39, Sami Tolvanen wrote: > Add a basic DWARF parser, which uses libdw to traverse the debugging > information in an object file and looks for functions and variables. > In follow-up patches, this will be expanded to produce symbol versions > for CONFIG_MODVERSIONS from DWARF. > > Signed-off-by: Sami Tolvanen <samitolvanen@xxxxxxxxxx> > --- > kernel/module/Kconfig | 8 ++ > scripts/Makefile | 1 + > scripts/gendwarfksyms/.gitignore | 2 + > scripts/gendwarfksyms/Makefile | 7 ++ > scripts/gendwarfksyms/dwarf.c | 87 +++++++++++++++ > scripts/gendwarfksyms/gendwarfksyms.c | 146 ++++++++++++++++++++++++++ > scripts/gendwarfksyms/gendwarfksyms.h | 78 ++++++++++++++ > 7 files changed, 329 insertions(+) > create mode 100644 scripts/gendwarfksyms/.gitignore > create mode 100644 scripts/gendwarfksyms/Makefile > create mode 100644 scripts/gendwarfksyms/dwarf.c > create mode 100644 scripts/gendwarfksyms/gendwarfksyms.c > create mode 100644 scripts/gendwarfksyms/gendwarfksyms.h > > [...] > +static int parse_options(int argc, const char **argv) > +{ > + for (int i = 1; i < argc; i++) { > + bool flag = false; > + > + for (int j = 0; j < ARRAY_SIZE(options); j++) { > + if (strcmp(argv[i], options[j].arg)) > + continue; > + > + *options[j].flag = true; > + > + if (options[j].param) { > + if (++i >= argc) { > + error("%s needs an argument", > + options[j].arg); > + return -1; > + } > + > + *options[j].param = argv[i]; > + } > + > + flag = true; > + break; > + } > + > + if (!flag) > + object_files[object_count++] = argv[i]; I would rather add a check that this doesn't produce an out-of-bounds access. > [...] > +int main(int argc, const char **argv) > +{ > + unsigned int n; > + > + if (parse_options(argc, argv) < 0) > + return usage(); > + > + for (n = 0; n < object_count; n++) { > + Dwfl *dwfl; > + int fd; > + > + fd = open(object_files[n], O_RDONLY); > + if (fd == -1) { > + error("open failed for '%s': %s", object_files[n], > + strerror(errno)); > + return -1; > + } > + > + dwfl = dwfl_begin(&callbacks); > + if (!dwfl) { > + error("dwfl_begin failed for '%s': %s", object_files[n], > + dwarf_errmsg(-1)); > + return -1; > + } > + > + if (!dwfl_report_offline(dwfl, object_files[n], object_files[n], > + fd)) { > + error("dwfl_report_offline failed for '%s': %s", > + object_files[n], dwarf_errmsg(-1)); > + return -1; > + } > + > + dwfl_report_end(dwfl, NULL, NULL); > + > + if (dwfl_getmodules(dwfl, &process_modules, NULL, 0)) { > + error("dwfl_getmodules failed for '%s'", > + object_files[n]); > + return -1; > + } I see that libdwfl has also directly function dwfl_nextcu(). Would it make sense to use it to simplify the code? > + > + dwfl_end(dwfl); > + close(fd); Isn't fd consumed by dwfl_report_offline() on success? I'm seeing EBADF from this close() call. > + } > + > + return 0; > +} -- Thanks, Petr