nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 #include <plugin.h>
2 #include <tree.h>
3 #include <print-tree.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <arpa/inet.h>
7 #include <c-family/c-pragma.h>
8  
9 static tree handle_nexmon_place_at_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attr);
10  
11 int plugin_is_GPL_compatible = 1;
12  
13 static const char *objfile = "patch.o";
14 static const char *fwfile = "fw_bcmdhd.bin";
15 static const char *prefile = "nexmon.generated.pre";
16 static const char *targetregion = NULL;
17 static unsigned int ramstart = 0x180000;
18 static unsigned int chipver = 0;
19 static unsigned int fwver = 0;
20  
21 static FILE *pre_fp;
22  
23 static struct attribute_spec user_attr =
24 {
25 .name = "at",
26 .min_length = 1,
27 .max_length = 4,
28 .decl_required = true,
29 .type_required = false,
30 .function_type_required = false,
31 .handler = handle_nexmon_place_at_attribute,
32 .affects_type_identity = false,
33 };
34  
35 static tree
36 handle_nexmon_place_at_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attr)
37 {
38 //tree itr;
39 tree tmp_tree;
40  
41 const char *decl_name = IDENTIFIER_POINTER(DECL_NAME(*node));
42 //const char *attr_name = IDENTIFIER_POINTER(name);
43 //const char *param1_str = TREE_STRING_POINTER(TREE_VALUE(args));
44 const char *region = NULL;
45 unsigned int addr = 0;
46 bool is_dummy = false;
47 bool is_region = false;
48 bool is_flashpatch = false;
49 unsigned int chipver_local = 0;
50 unsigned int fwver_local = 0;
51  
52 if (TREE_CODE(TREE_VALUE(args)) == STRING_CST) {
53 region = TREE_STRING_POINTER(TREE_VALUE(args));
54 is_region = true;
55 } else if (TREE_CODE(TREE_VALUE(args)) == INTEGER_CST) {
56 addr = TREE_INT_CST_LOW(TREE_VALUE(args));
57 }
58  
59 tmp_tree = TREE_CHAIN(args);
60 if(tmp_tree != NULL_TREE) {
61 is_dummy = strstr(TREE_STRING_POINTER(TREE_VALUE(tmp_tree)), "dummy");
62 is_flashpatch = strstr(TREE_STRING_POINTER(TREE_VALUE(tmp_tree)), "flashpatch");
63  
64 tmp_tree = TREE_CHAIN(tmp_tree);
65 if(tmp_tree != NULL_TREE) {
66 chipver_local = TREE_INT_CST_LOW(TREE_VALUE(tmp_tree));
67  
68 tmp_tree = TREE_CHAIN(tmp_tree);
69 if(tmp_tree != NULL_TREE) {
70 fwver_local = TREE_INT_CST_LOW(TREE_VALUE(tmp_tree));
71 }
72 }
73 }
74  
75 printf("decl_name: %s\n", decl_name);
76  
77 //printf("attr_name: %s\n", attr_name);
78  
79 //printf("align: %d\n", DECL_COMMON_CHECK (*node)->decl_common.align);
80 if (DECL_COMMON_CHECK (*node)->decl_common.align == 32 && (addr & 1))
81 DECL_COMMON_CHECK (*node)->decl_common.align = 8;
82  
83 if (DECL_COMMON_CHECK (*node)->decl_common.align == 32 && (addr & 2))
84 DECL_COMMON_CHECK (*node)->decl_common.align = 16;
85 //printf("align: %d\n", DECL_COMMON_CHECK (*node)->decl_common.align);
86  
87 //for(itr = args; itr != NULL_TREE; itr = TREE_CHAIN(itr)) {
88 // printf("arg: %s %08x\n", TREE_STRING_POINTER(TREE_VALUE(itr)), (unsigned int) strtol(TREE_STRING_POINTER(TREE_VALUE(itr)), NULL, 0));
89 //debug_tree(itr);
90 //debug_tree(TREE_VALUE(itr));
91 //}
92  
93 if ((chipver == 0 || chipver_local == 0 || chipver == chipver_local) && (fwver == 0 || fwver_local == 0 || fwver == fwver_local)) {
94 if (is_region) {
95 fprintf(pre_fp, "%s REGION %s %s\n", region, objfile, decl_name);
96 } else if (is_flashpatch) {
97 fprintf(pre_fp, "0x%08x FLASHPATCH %s %s\n", addr, objfile, decl_name);
98 } else if (is_dummy) {
99 fprintf(pre_fp, "0x%08x DUMMY %s %s\n", addr, objfile, decl_name);
100 } else {
101 fprintf(pre_fp, "0x%08x PATCH %s %s\n", addr, objfile, decl_name);
102 }
103 }
104  
105 //debug_tree(*node);
106 //debug_tree(name);
107 return NULL_TREE;
108 }
109  
110 static void
111 register_attributes(void *event_data, void *data)
112 {
113 register_attribute(&user_attr);
114 }
115  
116 static void
117 handle_pragma_targetregion(cpp_reader *dummy)
118 {
119 tree message = 0;
120 if (pragma_lex(&message) != CPP_STRING) {
121 printf ("<#pragma NEXMON targetregion> is not a string");
122 return;
123 }
124  
125 if (TREE_STRING_LENGTH (message) > 1) {
126 targetregion = TREE_STRING_POINTER (message);
127 fprintf(pre_fp, "%s TARGETREGION %s\n", targetregion, objfile);
128 }
129 }
130  
131 static void
132 register_pragmas(void *event_data, void *data)
133 {
134 c_register_pragma("NEXMON", "targetregion", handle_pragma_targetregion);
135 }
136  
137 static void
138 handle_plugin_finish(void *event_data, void *data)
139 {
140 fclose(pre_fp);
141 }
142  
143 int
144 plugin_init(struct plugin_name_args *info, struct plugin_gcc_version *ver)
145 {
146 int i = 0;
147 for (i = 0; i < info->argc; i++) {
148 if (!strcmp(info->argv[i].key, "objfile")) {
149 objfile = info->argv[i].value;
150 } else if (!strcmp(info->argv[i].key, "prefile")) {
151 prefile = info->argv[i].value;
152 } else if (!strcmp(info->argv[i].key, "fwfile")) {
153 fwfile = info->argv[i].value;
154 } else if (!strcmp(info->argv[i].key, "ramstart")) {
155 ramstart = (unsigned int) strtol(info->argv[i].value, NULL, 0);
156 } else if (!strcmp(info->argv[i].key, "chipver")) {
157 chipver = (unsigned int) strtol(info->argv[i].value, NULL, 0);
158 } else if (!strcmp(info->argv[i].key, "fwver")) {
159 fwver = (unsigned int) strtol(info->argv[i].value, NULL, 0);
160 }
161 }
162  
163 pre_fp = fopen(prefile, "a");
164  
165 if (!pre_fp) {
166 fprintf(stderr, "gcc_nexmon_plugin: Pre file not writeable! (error)\n");
167 return -1;
168 }
169  
170 register_callback("nexmon", PLUGIN_ATTRIBUTES, register_attributes, NULL);
171 register_callback("nexmon", PLUGIN_PRAGMAS, register_pragmas, NULL);
172 register_callback("nexmon", PLUGIN_FINISH, handle_plugin_finish, NULL);
173  
174 return 0;
175 }