public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
@ 2011-05-25  0:41 Abhijit Nandy
  2011-05-25  8:20 ` Ian Lance Taylor
  0 siblings, 1 reply; 10+ messages in thread
From: Abhijit Nandy @ 2011-05-25  0:41 UTC (permalink / raw)
  To: gcc

Hi,

I an writing a plugin to insert some function calls and extern variable 
declarations into a C program.

If the original program is the following :
#include <stdio.h>
#include "molen_htx.h"

int main(void)
{
      printf("hello from program\n");
      return 0;
}

It has to be transformed to :

#include <stdio.h>
#include "molen_htx.h"

extern char _binary_ccu_start;

int main(void)
{
    char *p = &_binary_ccu_start;
    molen_elfset(p);
    molen_reset();

    printf("hello from program\n");
    return 0;
}

------------------------------------------------------------------------------------------------------
I have got about half way through this using the following gcc plugin code :

------------------------------------------plugin.c-------------------------------------------------------------

//Global tree nodes
tree elfset_decl = NULL;
tree reset_decl = NULL;

//Check the attribute for a function and capture the AST tree node into a 
global tree node
static tree handle_user_attribute(tree *node, tree name, tree args, int 
flags, bool *no_add_attrs)
{
    if(node == NULL || TREE_CODE(*node) != FUNCTION_DECL)
    {
        *no_add_attrs = true;
        return NULL_TREE;
    }
    if(args != NULL)
    {
        if(!(TREE_CODE(TREE_VALUE(args)) == STRING_CST))
        {
            warning(0, "argument to user attribute should be a string");
            *no_add_attrs = true;
            return NULL_TREE;
        }
        const char *arg = TREE_STRING_POINTER(TREE_VALUE(args));
       if(strcmp(arg, "elfset") == 0)
        {
            elfset_decl = *node;
        }
        else if(strcmp(arg, "reset") == 0)
        {
            reset_decl = *node;
        }
    }
    return NULL_TREE;
}

//Insert the molen_elfset() call
void insert_elfset_call()
{
    basic_block bb = ENTRY_BLOCK_PTR->next_bb;
    gimple_stmt_iterator gsi = gsi_start_bb(bb);

    //Simple assignment statement
    tree lhs = create_tmp_var(TREE_TYPE(TREE_TYPE(elfset_decl)), "p");
    tree rhs = create_tmp_var(TREE_TYPE(TREE_TYPE(elfset_decl)), "q");
    gimple assign = gimple_build_assign_stat (lhs,  rhs);
    gsi_insert_before(&gsi, assign, GSI_SAME_STMT);

    //Build a function call from the compiled molen_elfset() code first : 
function has unique attribute which helps pick it using elfset_decl
    gimple elfcall = gimple_build_call(elfset_decl,  1, temp);
    gsi_insert_before(&gsi, elfcall, GSI_SAME_STMT);
    cgraph_create_edge(cgraph_node(current_function_decl),
            cgraph_node(elfset_decl), elfcall, bb->count,
            compute_call_stmt_bb_frequency(current_function_decl, bb), 
bb->loop_depth);
}

//Insert the molen_htx_init() call,
void insert_init_call()
{
    basic_block bb = ENTRY_BLOCK_PTR->next_bb;
    gimple_stmt_iterator gsi = gsi_start_bb(bb);

    //Insert function call graph edge from current function to 
molen_htx_init()
    gimple call = gimple_build_call(init_decl, 0);
    gsi_insert_before(&gsi, call, GSI_SAME_STMT);

    /* Create edge from Function CALLER to CALLEE in the cgraph. See 
http://opensource.apple.com/source/gcc/gcc-5572.10.2/gcc/cgraph.c*/
    cgraph_create_edge(cgraph_node(current_function_decl),
            cgraph_node(init_decl), call, bb->count,
            compute_call_stmt_bb_frequency(current_function_decl, bb), 
bb->loop_depth);

}

//Insert the molen_reset() call
void insert_reset_call()
{
    basic_block bb = ENTRY_BLOCK_PTR->next_bb;
    gimple_stmt_iterator gsi = gsi_start_bb(bb);

    gimple resetcall = gimple_build_call(reset_decl, 0);
    gsi_insert_before(&gsi, resetcall, GSI_SAME_STMT);
    cgraph_create_edge(cgraph_node(current_function_decl),
            cgraph_node(reset_decl), resetcall, bb->count,
            compute_call_stmt_bb_frequency(current_function_decl, bb), 
bb->loop_depth);

}


//The pass function called by GCC to add / remove compiled code using gimple
static unsigned int replace_func(void)
{
    if(is_replace_function(current_function_decl))
    {
        if(!have_molen_functions())
            return 1;
        replace_function_body();
    }
    else if(MAIN_NAME_P(DECL_NAME(current_function_decl)))
    {
        if(!have_molen_functions())
            return 1;

        insert_reset_call();    //Call in reverse order of the actual 
statment order : as inserts happen before 1st stmnt in the functions
        insert_elfset_call();
        insert_init_call();

    }
    return 0;
}

//Pass information structure
static struct gimple_opt_pass pass_replace =
{
    {
        GIMPLE_PASS,
        "replace",
        NULL,
        replace_func,
        NULL,
        NULL,
        0,
        0,
        PROP_gimple_any | PROP_cfg,
        0,
        0,
        0,
        TODO_remove_unused_locals|TODO_cleanup_cfg|TODO_dump_func
    }
};

//Called automatically to initialize the pass
int plugin_init (struct plugin_name_args *plugin_info, struct 
plugin_gcc_version *version)
{
    const char *plugin_name = plugin_info->base_name;
    struct register_pass_info replace_pass_info;

    replace_pass_info.pass = &pass_replace.pass;
    replace_pass_info.reference_pass_name = "inline_param";
    replace_pass_info.ref_pass_instance_number = 1;
    replace_pass_info.pos_op = PASS_POS_INSERT_AFTER;

    register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, 
&replace_pass_info);
    register_callback (plugin_name, PLUGIN_ATTRIBUTES, register_attributes, 
NULL);
    printf("plugin init %s\n", plugin_name);
    return 0;
}
-------------------------------------------------------------------------------------------------------------------------

The functions are declared in a header file included in plugin.c using 
attributes  such as  :
__attribute__((user("elfset")))
char* molen_elfset(char* start);

__attribute__((user("reset")))
void molen_reset(void);

So I basically use the attributes to find the proper function node and 
insert them in the beginning of main()

My output is as follows :
;; Function main (main)

main ()
{
  char * p.1;
  char * p.0;

<bb 2>:
  molen_htx_init ();
  p.0 = p.1;
  molen_elfset (p.0);
  molen_reset ();

  return 0;

}

This is ok but I am unable to figure out how to insert a statement like the 
following in global scope:
extern char _binary_ccu_start;

or to make an assigment like the following inside main :
char *p = &_binary_ccu_start;

Is this possible to do using a plugin ?

Abhi 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
  2011-05-25  0:41 How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass Abhijit Nandy
@ 2011-05-25  8:20 ` Ian Lance Taylor
  2011-05-31 12:47   ` Abhijit Nandy
  0 siblings, 1 reply; 10+ messages in thread
From: Ian Lance Taylor @ 2011-05-25  8:20 UTC (permalink / raw)
  To: Abhijit Nandy; +Cc: gcc

"Abhijit Nandy" <abhijit.nandy@gmail.com> writes:

> This is ok but I am unable to figure out how to insert a statement
> like the following in global scope:
> extern char _binary_ccu_start;
>
> or to make an assigment like the following inside main :
> char *p = &_binary_ccu_start;
>
> Is this possible to do using a plugin ?

You need to create a VAR_DECL with TREE_STATIC set to 1 and pass it to
rest_of_decl_compilation.  Then you can get an expression which takes it
address by passing the decl to build_fold_addr_expr.

Ian

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
  2011-05-25  8:20 ` Ian Lance Taylor
@ 2011-05-31 12:47   ` Abhijit Nandy
  2011-05-31 19:40     ` Ian Lance Taylor
  0 siblings, 1 reply; 10+ messages in thread
From: Abhijit Nandy @ 2011-05-31 12:47 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

Hi Ian,

Thanks for the pointers. I have been trying to make a simple VAR_DECL using 
the following call :

tree type_node = make_node(POINTER_TYPE);
//TYPE_NAME(type_node) = type_id;
tree var_decl = build0(VAR_DECL, type_node);

I was using this post as a guide :
http://gcc.gnu.org/ml/gcc/2007-01/msg00536.html

But I get a segmentation fault :
testcode.c: In function 'main':
testcode.c:26:7: warning: unused variable 'q'
*** WARNING *** there are active plugins, do not report this as a bug unless 
you
can reproduce it without enabling any plugins.
Event                            | Plugins
PLUGIN_ATTRIBUTES                | test_plugin
testcode.c:33:1: internal compiler error: Segmentation fault

Can someone please help me out on how to complete the variable declaration 
and gimplify it.

-------------------

What I am attempting to do is insert the assignment statement in main() as 
follows(the global extern declaration also needs to be inserted but I can 
work it out afterwards):

extern char _binary_ccu_start;

int main (int argc, char **argv)
{
....
    char *p = &_binary_ccu_start;
...
}

Thanks,
Abhi

-----Original Message----- 
From: Ian Lance Taylor
Sent: Wednesday, May 25, 2011 2:39 AM
To: Abhijit Nandy
Cc: gcc
Subject: Re: How to insert external global variable declarations and pointer 
assignment statements through GCC plugin GIMPLE pass

"Abhijit Nandy" <abhijit.nandy@gmail.com> writes:

> This is ok but I am unable to figure out how to insert a statement
> like the following in global scope:
> extern char _binary_ccu_start;
>
> or to make an assigment like the following inside main :
> char *p = &_binary_ccu_start;
>
> Is this possible to do using a plugin ?

You need to create a VAR_DECL with TREE_STATIC set to 1 and pass it to
rest_of_decl_compilation.  Then you can get an expression which takes it
address by passing the decl to build_fold_addr_expr.

Ian 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
  2011-05-31 12:47   ` Abhijit Nandy
@ 2011-05-31 19:40     ` Ian Lance Taylor
  2011-06-14 17:29       ` Abhijit Nandy
  0 siblings, 1 reply; 10+ messages in thread
From: Ian Lance Taylor @ 2011-05-31 19:40 UTC (permalink / raw)
  To: Abhijit Nandy; +Cc: gcc

"Abhijit Nandy" <abhijit.nandy@gmail.com> writes:

> Thanks for the pointers. I have been trying to make a simple VAR_DECL
> using the following call :
>
> tree type_node = make_node(POINTER_TYPE);
> //TYPE_NAME(type_node) = type_id;
> tree var_decl = build0(VAR_DECL, type_node);

Use build_decl.

> testcode.c:33:1: internal compiler error: Segmentation fault

When you get a segmentation fault, your first step should be to use the
debugger to find out what went wrong.  That will normally point you in
the right direction.

Ian

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
  2011-05-31 19:40     ` Ian Lance Taylor
@ 2011-06-14 17:29       ` Abhijit Nandy
  2011-06-14 17:39         ` Ian Lance Taylor
  0 siblings, 1 reply; 10+ messages in thread
From: Abhijit Nandy @ 2011-06-14 17:29 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

Hi Ian,

Thanks so much for the pointers. I was able to insert most of the lines 
except for the global extern declaration which is the following :

extern char _binary_ccu_start;


My current plugin code is as follows :

void insert_elfset_call()
{
    basic_block bb = ENTRY_BLOCK_PTR->next_bb;
    gimple_stmt_iterator gsi = gsi_start_bb(bb);

    tree temp = create_tmp_var(TREE_TYPE(TREE_TYPE(elfset_decl)), "p");

    tree var_decl = build_decl(UNKNOWN_LOCATION, VAR_DECL, 
get_identifier("_binary_ccu_start"), char_type_node);
    TREE_STATIC(var_decl) = 1;
    DECL_EXTERNAL(var_decl) = 1;                            //this does not 
cause var_decl to also be declared as extern globally
    rest_of_decl_compilation (var_decl, 1, 0);

    tree addr_var_decl = build_fold_addr_expr(var_decl);

    gimple assign = gimple_build_assign_stat (temp, addr_var_decl);
    gsi_insert_before(&gsi, assign, GSI_SAME_STMT);

    //Build a function call from the compiled molen_elfset() code first : 
function has unique attribute marked with __attribute__((user("replace"))) 
which helps pick it using elfset_decl
    gimple elfcall = gimple_build_call(elfset_decl,  1, temp);

    //gsi_insert_after (&gsi, elfcall, GSI_CONTINUE_LINKING);//can be used 
to insert the call after 1st statement, still needs function call graph edge
    gsi_insert_before(&gsi, elfcall, GSI_SAME_STMT);

    cgraph_create_edge(cgraph_node(current_function_decl),
            cgraph_node(elfset_decl), elfcall, bb->count,
            compute_call_stmt_bb_frequency(current_function_decl, bb), 
bb->loop_depth);
}


I get the following output from it :

;; Function main (main)

main ()
{
  char * p.1;

<bb 2>:
.....
  p.1 = &_binary_ccu_start;
  molen_elfset (p.1);
....
}
------------------------------------------------------------------------------------

To recall I am trying to insert the following in a C program :

extern char _binary_ccu_start;

int main (int argc, char **argv)
{
....
    char *p = &_binary_ccu_start;
    molen_elfset(p);
...
}


Thanks,
Abhi


-----Original Message----- 
From: Ian Lance Taylor
Sent: Tuesday, May 31, 2011 4:36 PM
To: Abhijit Nandy
Cc: gcc
Subject: Re: How to insert external global variable declarations and pointer 
assignment statements through GCC plugin GIMPLE pass

"Abhijit Nandy" <abhijit.nandy@gmail.com> writes:

> Thanks for the pointers. I have been trying to make a simple VAR_DECL
> using the following call :
>
> tree type_node = make_node(POINTER_TYPE);
> //TYPE_NAME(type_node) = type_id;
> tree var_decl = build0(VAR_DECL, type_node);

Use build_decl.

> testcode.c:33:1: internal compiler error: Segmentation fault

When you get a segmentation fault, your first step should be to use the
debugger to find out what went wrong.  That will normally point you in
the right direction.

Ian 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
  2011-06-14 17:29       ` Abhijit Nandy
@ 2011-06-14 17:39         ` Ian Lance Taylor
  2011-06-14 18:36           ` Abhijit Nandy
  0 siblings, 1 reply; 10+ messages in thread
From: Ian Lance Taylor @ 2011-06-14 17:39 UTC (permalink / raw)
  To: Abhijit Nandy; +Cc: gcc

"Abhijit Nandy" <abhijit.nandy@gmail.com> writes:

> I get the following output from it :
>
> ;; Function main (main)
>
> main ()
> {
>  char * p.1;
>
> <bb 2>:
> .....
>  p.1 = &_binary_ccu_start;
>  molen_elfset (p.1);
> ....
> }
> ------------------------------------------------------------------------------------
>
> To recall I am trying to insert the following in a C program :
>
> extern char _binary_ccu_start;
>
> int main (int argc, char **argv)
> {
> ....
>    char *p = &_binary_ccu_start;
>    molen_elfset(p);
> ...
> }

If you are looking at a dump file, then it seems to me that you are
getting what you want.  A dump file is not a C file; it doesn't list the
extern declarations explicitly.

Let me know if I'm missing something.

Ian

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
  2011-06-14 17:39         ` Ian Lance Taylor
@ 2011-06-14 18:36           ` Abhijit Nandy
  2011-06-14 20:03             ` Ian Lance Taylor
  0 siblings, 1 reply; 10+ messages in thread
From: Abhijit Nandy @ 2011-06-14 18:36 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

Yes you are right I am looking at a dump file.

My C input file is testcode.c and after I compile with the plugin enabled as 
:

gcc -fplugin=./test_plugin.so -Wall -fdump-tree-gimple -fdump-tree-all 
testcode.c molen_htx.c -o testcode

The molen_htx.c has the molen_elfset()

I get the following linker error :

root@slax:/mnt/f/Thesis/gcc-pluginelf# make testcode
cc -I/usr/lib/gcc/i486-slackware-linux/4.5.2/plugin/include -fPIC -Wall   -c 
 -o test_plugin.o test_plugin.c
gcc -shared test_plugin.o -o test_plugin.so
gcc -fplugin=./test_plugin.so -Wall -fdump-tree-gimple -fdump-tree-all 
testcode.c molen_htx.c -o testcode
plugin init test_plugin
testcode.c: In function 'main':
testcode.c:26:7: warning: unused variable 'q'
plugin init test_plugin
/tmp/ccLUccsU.o: In function `main':
testcode.c:(.text+0x82): undefined reference to `_binary_ccu_start' 
<---------------
collect2: ld returned 1 exit status
make: *** [testcode] Error 1


A dump file called testcode.c.220t.replace is produced which does not show 
the global declaration(if it is being inserted at all)

But the undefined reference implies that the global extern declaration was 
not inserted.

Thanks,
Abhi

-----Original Message----- 
From: Ian Lance Taylor
Sent: Tuesday, June 14, 2011 7:18 PM
To: Abhijit Nandy
Cc: gcc
Subject: Re: How to insert external global variable declarations and pointer 
assignment statements through GCC plugin GIMPLE pass

"Abhijit Nandy" <abhijit.nandy@gmail.com> writes:

> I get the following output from it :
>
> ;; Function main (main)
>
> main ()
> {
>  char * p.1;
>
> <bb 2>:
> .....
>  p.1 = &_binary_ccu_start;
>  molen_elfset (p.1);
> ....
> }
> ------------------------------------------------------------------------------------
>
> To recall I am trying to insert the following in a C program :
>
> extern char _binary_ccu_start;
>
> int main (int argc, char **argv)
> {
> ....
>    char *p = &_binary_ccu_start;
>    molen_elfset(p);
> ...
> }

If you are looking at a dump file, then it seems to me that you are
getting what you want.  A dump file is not a C file; it doesn't list the
extern declarations explicitly.

Let me know if I'm missing something.

Ian 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
  2011-06-14 18:36           ` Abhijit Nandy
@ 2011-06-14 20:03             ` Ian Lance Taylor
  2011-06-15  7:25               ` Abhijit Nandy
  0 siblings, 1 reply; 10+ messages in thread
From: Ian Lance Taylor @ 2011-06-14 20:03 UTC (permalink / raw)
  To: Abhijit Nandy; +Cc: gcc

"Abhijit Nandy" <abhijit.nandy@gmail.com> writes:

> My C input file is testcode.c and after I compile with the plugin
> enabled as :
>
> gcc -fplugin=./test_plugin.so -Wall -fdump-tree-gimple -fdump-tree-all
> testcode.c molen_htx.c -o testcode
>
> The molen_htx.c has the molen_elfset()
>
> I get the following linker error :
>
> root@slax:/mnt/f/Thesis/gcc-pluginelf# make testcode
> cc -I/usr/lib/gcc/i486-slackware-linux/4.5.2/plugin/include -fPIC
> -Wall   -c 
> -o test_plugin.o test_plugin.c
> gcc -shared test_plugin.o -o test_plugin.so
> gcc -fplugin=./test_plugin.so -Wall -fdump-tree-gimple -fdump-tree-all
> testcode.c molen_htx.c -o testcode
> plugin init test_plugin
> testcode.c: In function 'main':
> testcode.c:26:7: warning: unused variable 'q'
> plugin init test_plugin
> /tmp/ccLUccsU.o: In function `main':
> testcode.c:(.text+0x82): undefined reference to `_binary_ccu_start'
> <---------------
> collect2: ld returned 1 exit status
> make: *** [testcode] Error 1
>
>
> A dump file called testcode.c.220t.replace is produced which does not
> show the global declaration(if it is being inserted at all)
>
> But the undefined reference implies that the global extern declaration
> was not inserted.

A global extern declaration is not a definition.  The variable needs to
be defined somewhere.

If your .c file has "extern char _binary_ccu_start;" you still need to
have some .c file which has "char _binary_ccu_start;", right?

Ian

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
  2011-06-14 20:03             ` Ian Lance Taylor
@ 2011-06-15  7:25               ` Abhijit Nandy
  2011-06-15  9:14                 ` Ian Lance Taylor
  0 siblings, 1 reply; 10+ messages in thread
From: Abhijit Nandy @ 2011-06-15  7:25 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

Hi Ian,

Thanks. Yes it was a basic mistake. I assumed that the undefined reference 
was due to the extern declaration not being inserted.

So I guess DECL_EXTERNAL(var_decl) = 1 causes the var_decl to be set as an 
external declaration in the following code  :

tree var_decl = build_decl(UNKNOWN_LOCATION, VAR_DECL, 
get_identifier("_binary_ccu_start"), char_type_node);
TREE_STATIC(var_decl) = 1;
DECL_EXTERNAL(var_decl) = 1;


I have another question. Right now I create the following declaration
char *p;

using :
tree temp = create_tmp_var(TREE_TYPE(TREE_TYPE(elfset_decl)), "p");

where elfset_decl is set to be char* in a separate function.

However is there another way to create a pointer to char, especially if I 
want the exact identifier 'p' instead of
char * p.1;

which the gimple pass dump is showing me.

I tried to do it as follows :
tree var_decl1 = build_decl(UNKNOWN_LOCATION, VAR_DECL, get_identifier("p"), 
char_type_node);
TREE_STATIC(var_decl1) = 0;
DECL_EXTERNAL(var_decl1) = 0;
rest_of_decl_compilation (var_decl1, 1, 0);

But nothing appears in the gimple pass dump. I think this may be due to not 
actually inserting the declaration in the tree using a gimple function.

Thanks,
Abhi


-----Original Message----- 
From: Ian Lance Taylor
Sent: Tuesday, June 14, 2011 7:38 PM
To: Abhijit Nandy
Cc: gcc
Subject: Re: How to insert external global variable declarations and pointer 
assignment statements through GCC plugin GIMPLE pass

"Abhijit Nandy" <abhijit.nandy@gmail.com> writes:

> My C input file is testcode.c and after I compile with the plugin
> enabled as :
>
> gcc -fplugin=./test_plugin.so -Wall -fdump-tree-gimple -fdump-tree-all
> testcode.c molen_htx.c -o testcode
>
> The molen_htx.c has the molen_elfset()
>
> I get the following linker error :
>
> root@slax:/mnt/f/Thesis/gcc-pluginelf# make testcode
> cc -I/usr/lib/gcc/i486-slackware-linux/4.5.2/plugin/include -fPIC
> -Wall   -c
> -o test_plugin.o test_plugin.c
> gcc -shared test_plugin.o -o test_plugin.so
> gcc -fplugin=./test_plugin.so -Wall -fdump-tree-gimple -fdump-tree-all
> testcode.c molen_htx.c -o testcode
> plugin init test_plugin
> testcode.c: In function 'main':
> testcode.c:26:7: warning: unused variable 'q'
> plugin init test_plugin
> /tmp/ccLUccsU.o: In function `main':
> testcode.c:(.text+0x82): undefined reference to `_binary_ccu_start'
> <---------------
> collect2: ld returned 1 exit status
> make: *** [testcode] Error 1
>
>
> A dump file called testcode.c.220t.replace is produced which does not
> show the global declaration(if it is being inserted at all)
>
> But the undefined reference implies that the global extern declaration
> was not inserted.

A global extern declaration is not a definition.  The variable needs to
be defined somewhere.

If your .c file has "extern char _binary_ccu_start;" you still need to
have some .c file which has "char _binary_ccu_start;", right?

Ian 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass
  2011-06-15  7:25               ` Abhijit Nandy
@ 2011-06-15  9:14                 ` Ian Lance Taylor
  0 siblings, 0 replies; 10+ messages in thread
From: Ian Lance Taylor @ 2011-06-15  9:14 UTC (permalink / raw)
  To: Abhijit Nandy; +Cc: gcc

"Abhijit Nandy" <abhijit.nandy@gmail.com> writes:

> So I guess DECL_EXTERNAL(var_decl) = 1 causes the var_decl to be set
> as an external declaration in the following code  :

Yes.  DECL_EXTERNAL corresponds to the "extern" storage class specifier
in C/C++.

> I have another question. Right now I create the following declaration
> char *p;
>
> using :
> tree temp = create_tmp_var(TREE_TYPE(TREE_TYPE(elfset_decl)), "p");
>
> where elfset_decl is set to be char* in a separate function.

That creates a temporary variable.

> However is there another way to create a pointer to char, especially
> if I want the exact identifier 'p' instead of
> char * p.1;
>
> which the gimple pass dump is showing me.
>
> I tried to do it as follows :
> tree var_decl1 = build_decl(UNKNOWN_LOCATION, VAR_DECL,
> get_identifier("p"), char_type_node);
> TREE_STATIC(var_decl1) = 0;
> DECL_EXTERNAL(var_decl1) = 0;
> rest_of_decl_compilation (var_decl1, 1, 0);
>
> But nothing appears in the gimple pass dump. I think this may be due
> to not actually inserting the declaration in the tree using a gimple
> function.

For a local variable you don't need to call rest_of_decl_compilation.
If you want a local variable which is not a temporary variable, then you
need to build a BLOCK and a BIND_EXPR which define the variable in some
scope.  The BIND_EXPR will point to the block, and the BIND_EXPR then
needs to be added into the function code somehow so that the rest of the
compiler sees it.

Ian

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-06-14 20:03 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-25  0:41 How to insert external global variable declarations and pointer assignment statements through GCC plugin GIMPLE pass Abhijit Nandy
2011-05-25  8:20 ` Ian Lance Taylor
2011-05-31 12:47   ` Abhijit Nandy
2011-05-31 19:40     ` Ian Lance Taylor
2011-06-14 17:29       ` Abhijit Nandy
2011-06-14 17:39         ` Ian Lance Taylor
2011-06-14 18:36           ` Abhijit Nandy
2011-06-14 20:03             ` Ian Lance Taylor
2011-06-15  7:25               ` Abhijit Nandy
2011-06-15  9:14                 ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).