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