On Mon, 2018-07-30 at 10:51 -0400, David Malcolm wrote:
> On Sun, 2018-07-29 at 13:41 -0700, Joe Perches wrote:
> > I would like to implement a gcc plugin that can compress an
> > __attribute__((format(printf, x, y))) const char array before
> > storage so that the formats can be size reduced when stored and
> > expanded appropriately before use.
> > 
> > As this is the first plugin I am trying to implement, I'm a bit
> > lost in details and I am looking for guidance.
> > 
> > Basically:
> > 
> > Take the printf_format_type CONST_DECL format being verified by
> > gcc/c-format-main.c and after the verification, compress the
> > format and its length before storage into its .read_only section.
> > 
> > A custom vsnprintf routine would expand the compressed format to
> > its original form before use.
> > 
> > All tips to necessary gcc plugin implementation details appreciated.
> 
> If I understand your idea correctly, you're wanting to write a plugin
> that turns something like:
> 
>   printf ("some format string %s %i %s etc\n", arg1, arg2, arg3);
> 
> into something like:
> 
>   your_custom_printf ("cmprssd_frmt_strng", arg1, arg2, arg3);

Thank you for the reply.

More or less, but not quite.

The idea is to use a specific __attribute__, here
format(printf, x, y), although it could be another
custom attribute, to identify which strings to store
in some compressed manner.

I want to compress some format strings and keep gcc's
ability to verify format and arg compatibility while
possibly duplicating storage for identical strings.

For example, this should store 2 strings in .rodata...

o original uncompressed "fmt: '%s'\n"
o and the compressed equivalent used only in the first
  compress_fmt call for the first argument.

$ cat t_format.c
__attribute__((format(printf, 1, 2)))
void compress_fmt(const char *fmt, ...);
void original_fmt(const char *fmt, ...);

#define FMT "fmt: '%s'\n"

void foo(void)
{
  const char *fmt = FMT;                // uncompressed

  compress_fmt(FMT, fmt);               // compressed and uncompressed
  original_fmt(FMT, fmt);               // uncompressed

  compress_fmt(fmt, fmt);               // uncompressed
}
$

Reply via email to