Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 09-Jun-97 - Original Version 00042 * 00043 * Description: 00044 * 00045 * This file contains the GDAR routines. The GDAR facility is an 00046 * SGI-internal capability for experimenting with the marking of 00047 * "Global Data And Routines". :-) 00048 * 00049 * ==================================================================== 00050 * ==================================================================== 00051 */ 00052 00053 #ifdef _NEW_SYMTAB 00054 // TODO_NEW_SYMTAB: figure out what needs to be done 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 /* Global Defines */ 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 /* Global Data */ 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 /* Token processing routine */ 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 /* Main routine */ 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 /* Sanity checks */ 00303 00304 if ((gdar_filename == NULL) || (global_symtab == NULL)) 00305 return; 00306 00307 00308 /* Initialization */ 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 /* Read and process GDAR file */ 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 /* Process all symbols in the global symbol table */ 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 /* Process all pu's in the file */ 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 /* Termination */ 00598 00599 (void) hdestroy (); 00600 free (string_table); 00601 00602 return; 00603 00604 } 00605 #endif /* _NEW_SYMTAB */