00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #ifdef _NEW_SYMTAB
00059
00060 #else
00061
00062 #include <stdio.h>
00063 #include <sys/types.h>
00064 #include <sys/stat.h>
00065 #include <search.h>
00066 #include <string.h>
00067 #include <stdlib.h>
00068 #include <unistd.h>
00069 #include <elf.h>
00070 #include <sys/elf_whirl.h>
00071
00072 #include "defs.h"
00073 #include "glob.h"
00074 #include "stab.h"
00075 #include "pu_info.h"
00076 #include "file_util.h"
00077 #include "gdar.h"
00078
00079
00080
00081
00082 #define GLOBAL 0
00083 #define STATIC 1
00084
00085 #define FUNCTION 0
00086 #define DATA 1
00087
00088 #define DELETE -9
00089 #define NOCHANGE 0
00090 #define PREEMPT 1
00091 #define HIDDEN 2
00092 #define INTERNAL 3
00093 #define GPREL 4
00094
00095 #define NOOPTION 0
00096 #define TRACE 1
00097 #define LIST 2
00098
00099 #define OFF 0
00100 #define ON 1
00101
00102 typedef enum {
00103 tok_GLOBAL,
00104 tok_STATIC,
00105 tok_FUNCTION,
00106 tok_DATA,
00107 tok_DEFAULT,
00108 tok_DELETE,
00109 tok_NOCHANGE,
00110 tok_PREEMPT,
00111 tok_HIDDEN,
00112 tok_INTERNAL,
00113 tok_GPREL,
00114 tok_OPTIONS,
00115 tok_TRACE,
00116 tok_LIST,
00117 tok_OFF,
00118 tok_ON,
00119 tok_name,
00120 tok_eof
00121 } TOKENS;
00122
00123
00124
00125
00126 static FILE *gdar_file;
00127
00128 static char *file_name;
00129 static INT32 file_name_len;
00130
00131 static char line_buf[256];
00132 static char *line_ptr;
00133
00134 static INT32 file_size;
00135 static INT32 string_size;
00136 static INT32 hash_size;
00137
00138 static struct stat stat_buf;
00139
00140 static INT32 global_flag = GLOBAL;
00141 static INT32 function_flag = FUNCTION;
00142 static INT32 type_flag = NOCHANGE;
00143 static INT32 option_flag = NOOPTION;
00144 static INT32 trace_flag = OFF;
00145
00146 static INT32 global_func_default = NOCHANGE;
00147 static INT32 global_data_default = NOCHANGE;
00148 static INT32 static_func_default = NOCHANGE;
00149
00150 static char *string_table;
00151 static char *string_ptr;
00152 static char *token_ptr;
00153
00154
00155
00156
00157 static INT32 get_token(void) {
00158
00159 char *token_start;
00160 INT32 token_size;
00161 BOOL char_found;
00162 BOOL colon_seen;
00163
00164 token_scan:
00165
00166 char_found = FALSE;
00167 colon_seen = FALSE;
00168
00169 while (!char_found) {
00170 if (*line_ptr == 0) {
00171 if (fgets (&line_buf[0], 256, gdar_file) == NULL)
00172 return tok_eof;
00173 line_ptr = &line_buf[0];
00174 } else if ((*line_ptr == ' ') || (*line_ptr == '\t') || (*line_ptr == '\n'))
00175 line_ptr++;
00176 else if (*line_ptr == '!')
00177 *line_ptr = 0;
00178 else
00179 char_found = TRUE;
00180 }
00181
00182 token_start = line_ptr++;
00183 while ((*line_ptr != 0) && (*line_ptr != ' ') && (*line_ptr != '\t') &&
00184 (*line_ptr != '!') && (*line_ptr != '\n')) {
00185 if (*line_ptr == ':')
00186 colon_seen = TRUE;
00187 line_ptr++;
00188 }
00189 token_size = line_ptr - token_start;
00190
00191 if (trace_flag == ON)
00192 printf ("-- GDAR token: %.*s\n", token_size, token_start);
00193
00194 switch (token_size) {
00195
00196 case 2:
00197 if (strncmp (token_start, "ON", 2) == 0)
00198 return tok_ON;
00199 break;
00200
00201 case 3:
00202 if (strncmp (token_start, "OFF", 3) == 0)
00203 return tok_OFF;
00204 break;
00205
00206 case 4:
00207 if (strncmp (token_start, "DATA", 4) == 0)
00208 return tok_DATA;
00209 else if (strncmp (token_start, "LIST", 4) == 0)
00210 return tok_LIST;
00211 break;
00212
00213 case 5:
00214 if (strncmp (token_start, "GPREL", 5) == 0)
00215 return tok_GPREL;
00216 else if (strncmp (token_start, "TRACE", 5) == 0)
00217 return tok_TRACE;
00218 break;
00219
00220 case 6:
00221 if (strncmp (token_start, "DELETE", 6) == 0)
00222 return tok_DELETE;
00223 else if (strncmp (token_start, "GLOBAL", 6) == 0)
00224 return tok_GLOBAL;
00225 else if (strncmp (token_start, "HIDDEN", 6) == 0)
00226 return tok_HIDDEN;
00227 else if (strncmp (token_start, "STATIC", 6) == 0)
00228 return tok_STATIC;
00229 break;
00230
00231 case 7:
00232 if (strncmp (token_start, "DEFAULT", 7) == 0)
00233 return tok_DEFAULT;
00234 else if (strncmp (token_start, "OPTIONS", 7) == 0)
00235 return tok_OPTIONS;
00236 else if (strncmp (token_start, "PREEMPT", 7) == 0)
00237 return tok_PREEMPT;
00238 break;
00239
00240 case 8:
00241 if (strncmp (token_start, "FUNCTION", 8) == 0)
00242 return tok_FUNCTION;
00243 else if (strncmp (token_start, "INTERNAL", 8) == 0)
00244 return tok_INTERNAL;
00245 else if (strncmp (token_start, "NOCHANGE", 8) == 0)
00246 return tok_NOCHANGE;
00247 break;
00248 }
00249
00250 if (token_size && (*token_start == '"')) {
00251 token_start++;
00252 token_size--;
00253 }
00254 if (token_size && (*(line_ptr - 1) == '"')) {
00255 token_size--;
00256 }
00257 if (token_size == 0)
00258 goto token_scan;
00259
00260 if (colon_seen) {
00261 if ((token_size > file_name_len) &&
00262 (strncmp (token_start, file_name, file_name_len) == 0) &&
00263 (*(token_start + file_name_len) == ':')) {
00264 token_start += file_name_len + 1;
00265 token_size -= file_name_len + 1;
00266 if (token_size == 0)
00267 goto token_scan;
00268 } else
00269 goto token_scan;
00270 }
00271
00272 token_ptr = string_ptr++;
00273 if (global_flag == GLOBAL)
00274 if (function_flag == FUNCTION)
00275 *token_ptr = 'F';
00276 else
00277 *token_ptr = 'D';
00278 else
00279 if (function_flag == FUNCTION)
00280 *token_ptr = 'f';
00281 else
00282 *token_ptr = 'd';
00283 (void) strncpy (string_ptr, token_start, token_size);
00284 string_ptr += token_size;
00285 *(string_ptr++) = 0;
00286
00287 return tok_name;
00288
00289 }
00290
00291
00292
00293
00294
00295 void Process_GDAR (char *gdar_filename, SYMTAB *global_symtab,
00296 struct pu_info **global_pu)
00297 {
00298 ST *st;
00299 char symbol[256];
00300 ENTRY item;
00301 ENTRY *found_item;
00302 struct pu_info **prev_pu_ptr;
00303 struct pu_info *curr_pu;
00304 struct pu_info *next_pu;
00305 BOOL delete_pu;
00306
00307
00308
00309 if ((gdar_filename == NULL) || (global_symtab == NULL))
00310 return;
00311
00312
00313
00314
00315 file_name = Remove_Extension (Last_Pathname_Component (Irb_File_Name));
00316 file_name_len = strlen(file_name);
00317
00318 if (stat (gdar_filename, &stat_buf) != 0) {
00319 return;
00320 }
00321 file_size = stat_buf.st_size;
00322
00323 if ((gdar_file = fopen (gdar_filename, "r")) == NULL) {
00324 return;
00325 }
00326 line_buf[0] = 0;
00327 line_ptr = &line_buf[0];
00328
00329 hash_size = file_size / 6;
00330 if (hcreate (hash_size) == 0) {
00331 fclose (gdar_file);
00332 return;
00333 }
00334
00335 string_size = file_size;
00336 if ((string_ptr = string_table = (char *) malloc(string_size)) == NULL) {
00337 (void) hdestroy ();
00338 fclose (gdar_file);
00339 return;
00340 }
00341
00342
00343
00344
00345 for (;;) {
00346
00347 switch (get_token()) {
00348
00349 case tok_GLOBAL:
00350 global_flag = GLOBAL;
00351 break;
00352
00353 case tok_STATIC:
00354 global_flag = STATIC;
00355 break;
00356
00357 case tok_FUNCTION:
00358 function_flag = FUNCTION;
00359 break;
00360
00361 case tok_DATA:
00362 function_flag = DATA;
00363 break;
00364
00365 case tok_DEFAULT:
00366 if (global_flag == GLOBAL)
00367 if (function_flag == FUNCTION)
00368 global_func_default = type_flag;
00369 else
00370 global_data_default = type_flag;
00371 else
00372 if (function_flag == FUNCTION)
00373 static_func_default = type_flag;
00374 break;
00375
00376 case tok_DELETE:
00377 type_flag = DELETE;
00378 break;
00379
00380 case tok_NOCHANGE:
00381 type_flag = NOCHANGE;
00382 break;
00383
00384 case tok_PREEMPT:
00385 type_flag = PREEMPT;
00386 break;
00387
00388 case tok_HIDDEN:
00389 type_flag = HIDDEN;
00390 break;
00391
00392 case tok_INTERNAL:
00393 type_flag = INTERNAL;
00394 break;
00395
00396 case tok_GPREL:
00397 type_flag = GPREL;
00398 break;
00399
00400 case tok_OPTIONS:
00401 option_flag = NOOPTION;
00402 break;
00403
00404 case tok_TRACE:
00405 option_flag = TRACE;
00406 break;
00407
00408 case tok_LIST:
00409 option_flag = LIST;
00410 break;
00411
00412 case tok_OFF:
00413 if (option_flag == TRACE)
00414 trace_flag = OFF;
00415 break;
00416
00417 case tok_ON:
00418 if (option_flag == TRACE)
00419 trace_flag = ON;
00420 break;
00421
00422 case tok_name:
00423 item.key = token_ptr;
00424 item.data = (void *) type_flag;
00425 (void) hsearch (item, ENTER);
00426 break;
00427
00428 case tok_eof:
00429 goto done;
00430
00431 }
00432
00433 }
00434
00435 done:
00436
00437 fclose (gdar_file);
00438
00439
00440
00441
00442 for (st = SYMTAB_symbols(global_symtab); st != NULL; st = ST_next(st)) {
00443
00444 if (trace_flag == ON)
00445 printf ("-- GDAR processing %s\n", ST_name(st));
00446
00447 if ((ST_symclass(st) == CLASS_FUNC) && (ST_export(st) != EXPORT_LOCAL) &&
00448 ((ST_sclass(st) == SCLASS_EXTERN) || (ST_sclass(st) == SCLASS_TEXT))) {
00449 symbol[0] = 'F';
00450 (void) strcpy (&symbol[1], ST_name(st));
00451 item.key = &symbol[0];
00452 found_item = hsearch (item, FIND);
00453 if (found_item) {
00454 if ((INT32) found_item->data == INTERNAL) {
00455 Set_ST_export (st, EXPORT_INTERNAL);
00456 } else if ((INT32) found_item->data == HIDDEN) {
00457 Set_ST_export (st, EXPORT_HIDDEN);
00458 } else if ((INT32) found_item->data == PREEMPT) {
00459 Set_ST_export (st, EXPORT_PREEMPTIBLE);
00460 }
00461 } else {
00462 if (global_func_default == INTERNAL) {
00463 Set_ST_export (st, EXPORT_INTERNAL);
00464 } else if (global_func_default == HIDDEN) {
00465 Set_ST_export (st, EXPORT_HIDDEN);
00466 } else if (global_func_default == PREEMPT) {
00467 Set_ST_export (st, EXPORT_PREEMPTIBLE);
00468 }
00469 }
00470 } else if ((ST_symclass(st) == CLASS_VAR) &&
00471 (ST_export(st) != EXPORT_LOCAL) &&
00472 ((ST_sclass(st) == SCLASS_EXTERN) ||
00473 (ST_sclass(st) == SCLASS_DGLOBAL) ||
00474 (ST_sclass(st) == SCLASS_UGLOBAL))) {
00475 symbol[0] = 'D';
00476 (void) strcpy (&symbol[1], ST_name(st));
00477 item.key = &symbol[0];
00478 found_item = hsearch (item, FIND);
00479 if (found_item) {
00480 if ((INT32) found_item->data == GPREL) {
00481 Set_ST_gprel (st);
00482 Set_ST_export (st, EXPORT_INTERNAL);
00483 } else if ((INT32) found_item->data == INTERNAL) {
00484 Set_ST_export (st, EXPORT_INTERNAL);
00485 } else if ((INT32) found_item->data == HIDDEN) {
00486 Set_ST_export (st, EXPORT_HIDDEN);
00487 } else if ((INT32) found_item->data == PREEMPT) {
00488 Set_ST_export (st, EXPORT_PREEMPTIBLE);
00489 }
00490 } else {
00491 if (global_data_default == GPREL) {
00492 Set_ST_gprel (st);
00493 Set_ST_export (st, EXPORT_INTERNAL);
00494 } else if (global_data_default == INTERNAL) {
00495 Set_ST_export (st, EXPORT_INTERNAL);
00496 } else if (global_data_default == HIDDEN) {
00497 Set_ST_export (st, EXPORT_HIDDEN);
00498 } else if (global_data_default == PREEMPT) {
00499 Set_ST_export (st, EXPORT_PREEMPTIBLE);
00500 }
00501 }
00502 } else if ((ST_symclass(st) == CLASS_FUNC) &&
00503 (ST_export(st) == EXPORT_LOCAL) &&
00504 (ST_sclass(st) == SCLASS_TEXT)) {
00505 symbol[0] = 'f';
00506 (void) strcpy (&symbol[1], ST_name(st));
00507 item.key = &symbol[0];
00508 found_item = hsearch (item, FIND);
00509 if (found_item) {
00510 if ((INT32) found_item->data == INTERNAL) {
00511 Set_ST_pu_no_gp_prolog (st);
00512 } else if ((INT32) found_item->data == HIDDEN) {
00513 Reset_ST_pu_no_gp_prolog (st);
00514 }
00515 } else {
00516 if (static_func_default == INTERNAL) {
00517 Set_ST_pu_no_gp_prolog (st);
00518 } else if (static_func_default == HIDDEN) {
00519 Reset_ST_pu_no_gp_prolog (st);
00520 }
00521 }
00522 } else if ((ST_symclass(st) == CLASS_VAR) &&
00523 (ST_export(st) == EXPORT_LOCAL) &&
00524 ((ST_sclass(st) == SCLASS_FSTATIC) ||
00525 (ST_sclass(st) == SCLASS_PSTATIC))) {
00526 symbol[0] = 'd';
00527 (void) strcpy (&symbol[1], ST_name(st));
00528 item.key = &symbol[0];
00529 found_item = hsearch (item, FIND);
00530 if (found_item) {
00531 if ((INT32) found_item->data == GPREL) {
00532 Set_ST_gprel (st);
00533 }
00534 }
00535 }
00536
00537 }
00538
00539
00540
00541
00542 if (*global_pu) {
00543
00544 prev_pu_ptr = global_pu;
00545 curr_pu = *global_pu;
00546 next_pu = curr_pu->next;
00547
00548 while (curr_pu) {
00549
00550 st = PU_Info_proc_sym(curr_pu);
00551 delete_pu = FALSE;
00552
00553 if (trace_flag == ON)
00554 printf ("-- GDAR pu %s\n", ST_name(st));
00555
00556 if ((ST_symclass(st) == CLASS_FUNC) &&
00557 (ST_export(st) != EXPORT_LOCAL) &&
00558 (ST_sclass(st) == SCLASS_TEXT)) {
00559 symbol[0] = 'F';
00560 (void) strcpy (&symbol[1], ST_name(st));
00561 item.key = &symbol[0];
00562 found_item = hsearch (item, FIND);
00563 if (found_item) {
00564 if ((INT32) found_item->data == DELETE)
00565 delete_pu = TRUE;
00566 } else {
00567 if (global_func_default == DELETE)
00568 delete_pu = TRUE;
00569 }
00570 } else if ((ST_symclass(st) == CLASS_FUNC) &&
00571 (ST_export(st) == EXPORT_LOCAL) &&
00572 (ST_sclass(st) == SCLASS_TEXT)) {
00573 symbol[0] = 'f';
00574 (void) strcpy (&symbol[1], ST_name(st));
00575 item.key = &symbol[0];
00576 found_item = hsearch (item, FIND);
00577 if (found_item) {
00578 if ((INT32) found_item->data == DELETE)
00579 delete_pu = TRUE;
00580 } else {
00581 if (static_func_default == DELETE)
00582 delete_pu = TRUE;
00583 }
00584 }
00585
00586 if (delete_pu) {
00587 Set_ST_export (st, EXPORT_INTERNAL);
00588 Set_ST_sclass (st, SCLASS_EXTERN);
00589 *prev_pu_ptr = next_pu;
00590 } else
00591 prev_pu_ptr = &(curr_pu->next);
00592
00593 curr_pu = next_pu;
00594 if (curr_pu)
00595 next_pu = curr_pu->next;
00596
00597 }
00598
00599 }
00600
00601
00602
00603
00604 (void) hdestroy ();
00605 free (string_table);
00606
00607 return;
00608
00609 }
00610 #endif