Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
gdar.cxx
Go to the documentation of this file.
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines