pahole: Introduce --compile to produce a compilable output

This is the same strategy adopted by the bpftool when generating a
vmlinux file using:

  $ bpftool btf dump file vmlinux format c > vmlinux.h

Testing it:

  $ cat a.c
  #include "vmlinux.h"

  int main(void)
  {
        struct saved_context bla;

        bla.ds = 1;
        return bla.ds + 1;
  }
  $

  $ rm -f a ; make a
  cc     a.c   -o a
  $

Now using pahole:

  $ pahole --compile > vmlinux.h
  $ rm -f a ; make a
  $

This still have some issues, like:

  $ pahole --compile ../build/allyesconfig/drivers/spi/spi-bitbang.o > spi.h
  $ make spi
  cc     spi.c   -o spi
  In file included from spi.c:1:
  spi.h:7127:38: error: ‘txrx_word’ declared as function returning an array
   7127 |         u32 (*txrx_word)(struct spi_device *, unsigned int, u32, u8, unsigned int)[4]; /*   200    32 */
        |              ^~~~~~~~~
  make: *** [<builtin>: spi] Error 1
  $

The original source code:

	/* txrx_word[SPI_MODE_*]() just looks like a shift register */

                  u32 (*txrx_word[4])(struct spi_device *, unsigned int, u32, u8, unsigned int);

But this misgeneration predates this patch, so shouldn't prevent it from
being merged now, to make progress.

Also there are issues when generating from DWARF, so for now only accept
it if generating from BTF.

Trying to run it with dwarf produces, for now:

  $ pahole -F dwarf --compile vmlinux
  pahole: --compile currently only works with BTF.
  $

Cc: Tony Jones <tonyj@suse.de>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2022-02-08 15:54:50 -03:00
parent 4d004e2314
commit 65d7273668
3 changed files with 40 additions and 2 deletions

View File

@ -149,7 +149,7 @@ target_link_libraries(dtagnames dwarves)
set(pahole_SRCS pahole.c)
add_executable(pahole ${pahole_SRCS})
target_link_libraries(pahole dwarves dwarves_reorganize)
target_link_libraries(pahole dwarves dwarves_emit dwarves_reorganize)
set(pdwtags_SRCS pdwtags.c)
add_executable(pdwtags ${pdwtags_SRCS})

View File

@ -109,6 +109,18 @@ This is mostly needed so that pretty printing from BTF and DWARF can be
comparable when using using multiple threads to load DWARF data, when the order
that the types in the compile units is processed is not deterministic.
.TP
.B \-\-compile
Generate compileable code, with all definitions for all types, i.e.:
.PP
.nf
$ pahole --compile > vmlinux.h
.fi
Produces a header that can be included in a C source file and built. In
the example provided it will use the BTF info if available, otherwise will
look for a DWARF file matching the running kernel build-id.
.TP
.B \-\-count=COUNT
Pretty print the first COUNT records from input.

View File

@ -24,6 +24,7 @@
#include "dwarves_reorganize.h"
#include "dwarves.h"
#include "dwarves_emit.h"
#include "dutil.h"
//#include "ctf_encoder.h" FIXME: disabled, probably its better to move to Oracle's libctf
#include "btf_encoder.h"
@ -80,6 +81,9 @@ static const char *class_name;
static LIST_HEAD(class_names);
static char separator = '\t';
static bool compilable;
static struct type_emissions emissions;
static struct conf_fprintf conf = {
.emit_stats = 1,
};
@ -437,7 +441,12 @@ static void class_formatter(struct class *class, struct cu *cu, uint32_t id)
} else
conf.prefix = conf.suffix = NULL;
tag__fprintf(tag, cu, &conf, stdout);
if (compilable) {
if (type__emit_definitions(tag, cu, &emissions, stdout))
type__emit(tag, cu, NULL, NULL, stdout);
} else {
tag__fprintf(tag, cu, &conf, stdout);
}
putchar('\n');
}
@ -1127,6 +1136,7 @@ ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version;
#define ARGP_skip_encoding_btf_decl_tag 331
#define ARGP_skip_missing 332
#define ARGP_skip_encoding_btf_type_tag 333
#define ARGP_compile 334
static const struct argp_option pahole__options[] = {
{
@ -1455,6 +1465,11 @@ static const struct argp_option pahole__options[] = {
.key = ARGP_btf_gen_all,
.doc = "Allow using all the BTF features supported by pahole."
},
{
.name = "compile",
.key = ARGP_compile,
.doc = "Emit compilable types"
},
{
.name = "structs",
.key = ARGP_just_structs,
@ -1598,6 +1613,12 @@ static error_t pahole__options_parser(int key, char *arg,
formatter = class_name_formatter;
break;
// case 'Z': ctf_encode = 1; break; // FIXME: Disabled
case ARGP_compile:
compilable = true;
type_emissions__init(&emissions);
conf.no_semicolon = true;
conf.strip_inline = true;
break;
case ARGP_flat_arrays: conf.flat_arrays = 1; break;
case ARGP_suppress_aligned_attribute:
conf.suppress_aligned_attribute = 1; break;
@ -2870,6 +2891,11 @@ static enum load_steal_kind pahole_stealer(struct cu *cu,
{
int ret = LSK__DELETE;
if (compilable && strcmp(cu->dfops->name, "btf")) {
fprintf(stderr, "pahole: --compile currently only works with BTF.\n");
return LSK__STOP_LOADING;
}
if (!cu__filter(cu))
goto filter_it;