0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <sys/types.h>
0014 #include <stdlib.h>
0015 #include <string.h>
0016 #include <stdio.h>
0017 #include <regex.h>
0018 #include <libgen.h>
0019
0020 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
0021
0022
0023
0024
0025
0026
0027
0028 #define container_of(ptr, type, member) ({ \
0029 const typeof(((type *)0)->member)*__mptr = (ptr); \
0030 (type *)((char *)__mptr - offsetof(type, member)); })
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 struct list_head {
0043 struct list_head *next, *prev;
0044 };
0045
0046
0047 static inline void INIT_LIST_HEAD(struct list_head *list)
0048 {
0049 list->next = list;
0050 list->prev = list;
0051 }
0052
0053
0054
0055
0056
0057
0058
0059 #ifndef CONFIG_DEBUG_LIST
0060 static inline void __list_add(struct list_head *new,
0061 struct list_head *prev, struct list_head *next)
0062 {
0063 next->prev = new;
0064 new->next = next;
0065 new->prev = prev;
0066 prev->next = new;
0067 }
0068 #else
0069 extern void __list_add(struct list_head *new,
0070 struct list_head *prev, struct list_head *next);
0071 #endif
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 static inline void list_add_tail(struct list_head *new, struct list_head *head)
0082 {
0083 __list_add(new, head->prev, head);
0084 }
0085
0086
0087
0088
0089
0090
0091
0092 #define list_entry(ptr, type, member) \
0093 container_of(ptr, type, member)
0094
0095
0096
0097
0098
0099
0100
0101 #define list_for_each_entry(pos, head, member) \
0102 for (pos = list_entry((head)->next, typeof(*pos), member); \
0103 &pos->member != (head); \
0104 pos = list_entry(pos->member.next, typeof(*pos), member))
0105
0106 struct offset {
0107 struct list_head list;
0108 unsigned offset;
0109 };
0110
0111 struct table {
0112 struct list_head offsets;
0113 unsigned offset_max;
0114 unsigned nentry;
0115 unsigned *table;
0116 char *gpu_prefix;
0117 };
0118
0119 static struct offset *offset_new(unsigned o)
0120 {
0121 struct offset *offset;
0122
0123 offset = (struct offset *)malloc(sizeof(struct offset));
0124 if (offset) {
0125 INIT_LIST_HEAD(&offset->list);
0126 offset->offset = o;
0127 }
0128 return offset;
0129 }
0130
0131 static void table_offset_add(struct table *t, struct offset *offset)
0132 {
0133 list_add_tail(&offset->list, &t->offsets);
0134 }
0135
0136 static void table_init(struct table *t)
0137 {
0138 INIT_LIST_HEAD(&t->offsets);
0139 t->offset_max = 0;
0140 t->nentry = 0;
0141 t->table = NULL;
0142 }
0143
0144 static void table_print(struct table *t)
0145 {
0146 unsigned nlloop, i, j, n, c, id;
0147
0148 nlloop = (t->nentry + 3) / 4;
0149 c = t->nentry;
0150 printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
0151 t->nentry);
0152 for (i = 0, id = 0; i < nlloop; i++) {
0153 n = 4;
0154 if (n > c)
0155 n = c;
0156 c -= n;
0157 for (j = 0; j < n; j++) {
0158 if (j == 0)
0159 printf("\t");
0160 else
0161 printf(" ");
0162 printf("0x%08X,", t->table[id++]);
0163 }
0164 printf("\n");
0165 }
0166 printf("};\n");
0167 }
0168
0169 static int table_build(struct table *t)
0170 {
0171 struct offset *offset;
0172 unsigned i, m;
0173
0174 t->nentry = ((t->offset_max >> 2) + 31) / 32;
0175 t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
0176 if (t->table == NULL)
0177 return -1;
0178 memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
0179 list_for_each_entry(offset, &t->offsets, list) {
0180 i = (offset->offset >> 2) / 32;
0181 m = (offset->offset >> 2) & 31;
0182 m = 1 << m;
0183 t->table[i] ^= m;
0184 }
0185 return 0;
0186 }
0187
0188 static char gpu_name[10];
0189 static int parser_auth(struct table *t, const char *filename)
0190 {
0191 FILE *file;
0192 regex_t mask_rex;
0193 regmatch_t match[4];
0194 char buf[1024];
0195 size_t end;
0196 int len;
0197 int done = 0;
0198 int r;
0199 unsigned o;
0200 struct offset *offset;
0201 char last_reg_s[10];
0202 int last_reg;
0203
0204 if (regcomp
0205 (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
0206 fprintf(stderr, "Failed to compile regular expression\n");
0207 return -1;
0208 }
0209 file = fopen(filename, "r");
0210 if (file == NULL) {
0211 fprintf(stderr, "Failed to open: %s\n", filename);
0212 return -1;
0213 }
0214 fseek(file, 0, SEEK_END);
0215 end = ftell(file);
0216 fseek(file, 0, SEEK_SET);
0217
0218
0219 if (fgets(buf, 1024, file) == NULL) {
0220 fclose(file);
0221 return -1;
0222 }
0223
0224
0225
0226 sscanf(buf, "%9s %9s", gpu_name, last_reg_s);
0227 t->gpu_prefix = gpu_name;
0228 last_reg = strtol(last_reg_s, NULL, 16);
0229
0230 do {
0231 if (fgets(buf, 1024, file) == NULL) {
0232 fclose(file);
0233 return -1;
0234 }
0235 len = strlen(buf);
0236 if (ftell(file) == end)
0237 done = 1;
0238 if (len) {
0239 r = regexec(&mask_rex, buf, 4, match, 0);
0240 if (r == REG_NOMATCH) {
0241 } else if (r) {
0242 fprintf(stderr,
0243 "Error matching regular expression %d in %s\n",
0244 r, filename);
0245 fclose(file);
0246 return -1;
0247 } else {
0248 buf[match[0].rm_eo] = 0;
0249 buf[match[1].rm_eo] = 0;
0250 buf[match[2].rm_eo] = 0;
0251 o = strtol(&buf[match[1].rm_so], NULL, 16);
0252 offset = offset_new(o);
0253 table_offset_add(t, offset);
0254 if (o > t->offset_max)
0255 t->offset_max = o;
0256 }
0257 }
0258 } while (!done);
0259 fclose(file);
0260 if (t->offset_max < last_reg)
0261 t->offset_max = last_reg;
0262 return table_build(t);
0263 }
0264
0265 int main(int argc, char *argv[])
0266 {
0267 struct table t;
0268
0269 if (argc != 2) {
0270 fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
0271 exit(1);
0272 }
0273 table_init(&t);
0274 if (parser_auth(&t, argv[1])) {
0275 fprintf(stderr, "Failed to parse file %s\n", argv[1]);
0276 return -1;
0277 }
0278 table_print(&t);
0279 return 0;
0280 }