Working with C code

“Hello world”

Here’s a simple “hello world” C program:

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello, python\n");
}

Here’s a Python script that locates the function at one pass within the compile and prints various interesting things about it:

import gcc

# Here's a callback.  We will wire it up below:
def on_pass_execution(p, fn):
    # This pass is called fairly early on, per-function, after the
    # CFG has been built:
    if p.name == '*warn_function_return':
        # For this pass, "fn" will be an instance of gcc.Function:
        print('fn: %r' % fn)
        print('fn.decl.name: %r' % fn.decl.name)

        # fn.decl is an instance of gcc.FunctionDecl:
        print('return type: %r' % str(fn.decl.type.type))
        print('argument types: %r' % [str(t) for t in fn.decl.type.argument_types])

        assert isinstance(fn.cfg, gcc.Cfg) # None for some early passes
        assert len(fn.cfg.basic_blocks) == 3
        assert fn.cfg.basic_blocks[0] == fn.cfg.entry
        assert fn.cfg.basic_blocks[1] == fn.cfg.exit
        bb = fn.cfg.basic_blocks[2]
        for i,stmt in enumerate(bb.gimple):
            print 'gimple[%i]:' % i
            print '  str(stmt): %r' % str(stmt)
            print '  repr(stmt): %r' % repr(stmt)
            if isinstance(stmt, gcc.GimpleCall):
                from gccutils import pprint
                print('  type(stmt.fn): %r' % type(stmt.fn))
                print('  str(stmt.fn): %r' % str(stmt.fn))
                for i, arg in enumerate(stmt.args):
                    print('  str(stmt.args[%i]): %r' % (i, str(stmt.args[i])))
                print('  str(stmt.lhs): %s' % str(stmt.lhs))

# Wire up our callback:
gcc.register_callback(gcc.PLUGIN_PASS_EXECUTION,
                      on_pass_execution)

We can run the script during the compile like this:

./gcc-with-python script.py test.c

Here’s the expected output:

fn: gcc.Function('main')
fn.decl.name: 'main'
return type: 'int'
argument types: ['int', 'char * *']
gimple[0]:
  str(stmt): '__builtin_puts (&"Hello, python"[0]);'
  repr(stmt): 'gcc.GimpleCall()'
  type(stmt.fn): <type 'gcc.AddrExpr'>
  str(stmt.fn): '__builtin_puts'
  str(stmt.args[0]): '&"Hello, python"[0]'
  str(stmt.lhs): None
gimple[1]:
  str(stmt): 'return;'
  repr(stmt): 'gcc.GimpleReturn()'

Notice how the call to printf has already been optimized into a call to __builtin_puts.

Table Of Contents

Previous topic

Basic usage of the plugin

Next topic

Working with functions and control flow graphs

This Page