/[gxemul]/trunk/src/symbol.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/symbol.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 10 by dpavlin, Mon Oct 8 16:18:27 2007 UTC revision 40 by dpavlin, Mon Oct 8 16:22:11 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: symbol.c,v 1.26 2005/06/21 16:22:52 debug Exp $   *  $Id: symbol.c,v 1.38 2007/04/22 14:32:01 debug Exp $
29   *   *
30   *  Address to symbol translation routines.   *  Address to symbol translation routines.
31   *   *
32   *  This module is (probably) independant from the rest of the emulator.   *  This module is (probably) independent from the rest of the emulator.
33   *  symbol_init() must be called before any other function in this   *  symbol_init() must be called before any other function in this file is used.
  *  file is used.  
34   */   */
35    
36  #include <stdio.h>  #include <stdio.h>
37  #include <stdlib.h>  #include <stdlib.h>
38  #include <string.h>  #include <string.h>
39    
 #include "misc.h"  
   
40  #include "symbol.h"  #include "symbol.h"
41    
42    
# Line 94  int get_symbol_addr(struct symbol_contex Line 91  int get_symbol_addr(struct symbol_contex
91    
92    
93  /*  /*
94   *  get_symbol_name():   *  get_symbol_name_and_n_args():
95   *   *
96   *  Translate an address into a symbol name.  The return value is a pointer   *  Translate an address into a symbol name.  The return value is a pointer
97   *  to a static char array, containing the symbol name.  (In other words,   *  to a static char array, containing the symbol name.  (In other words,
# Line 107  int get_symbol_addr(struct symbol_contex Line 104  int get_symbol_addr(struct symbol_contex
104   *  0x1008, the symbol's name will be found in the static char array, and   *  0x1008, the symbol's name will be found in the static char array, and
105   *  *offset will be set to 0x8.   *  *offset will be set to 0x8.
106   *   *
107     *  If n_argsp is non-NULL, *n_argsp is set to the symbol's n_args value.
108     *
109   *  If no symbol was found, NULL is returned instead.   *  If no symbol was found, NULL is returned instead.
110   */   */
111  static char symbol_buf[SYMBOLBUF_MAX+1];  static char symbol_buf[SYMBOLBUF_MAX+1];
112  char *get_symbol_name(struct symbol_context *sc, uint64_t addr,  char *get_symbol_name_and_n_args(struct symbol_context *sc, uint64_t addr,
113          uint64_t *offset)          uint64_t *offset, int *n_argsp)
114  {  {
115          struct symbol *s;          struct symbol *s;
         int stepsize, ofs;  
116    
117          if (sc->n_symbols == 0)          if (sc->n_symbols == 0)
118                  return NULL;                  return NULL;
# Line 137  char *get_symbol_name(struct symbol_cont Line 135  char *get_symbol_name(struct symbol_cont
135                                              "%s", s->name);                                              "%s", s->name);
136                                  else                                  else
137                                          snprintf(symbol_buf, SYMBOLBUF_MAX,                                          snprintf(symbol_buf, SYMBOLBUF_MAX,
138                                              "%s+0x%lx", s->name, (long)                                              "%s+0x%"PRIx64, s->name, (uint64_t)
139                                              (addr - s->addr));                                              (addr - s->addr));
140                                  if (offset != NULL)                                  if (offset != NULL)
141                                          *offset = addr - s->addr;                                          *offset = addr - s->addr;
142                                    if (n_argsp != NULL)
143                                            *n_argsp = s->n_args;
144                                  return symbol_buf;                                  return symbol_buf;
145                          }                          }
146                          s = s->next;                          s = s->next;
147                  }                  }
148          } else {          } else {
149                  /*  Faster, O(log n) search:  */                  /*  Faster, O(log n) search:  */
150                  stepsize = sc->n_symbols / 2;                  int lowest = 0, highest = sc->n_symbols - 1;
151                  ofs = stepsize;                  while (lowest <= highest) {
152                  while (stepsize > 0 || (stepsize == 0 && ofs == 0)) {                          int ofs = (lowest + highest) / 2;
153                          s = sc->first_symbol + ofs;                          s = sc->first_symbol + ofs;
154    
155                          /*  Found a match?  */                          /*  Found a match?  */
# Line 159  char *get_symbol_name(struct symbol_cont Line 159  char *get_symbol_name(struct symbol_cont
159                                              "%s", s->name);                                              "%s", s->name);
160                                  else                                  else
161                                          snprintf(symbol_buf, SYMBOLBUF_MAX,                                          snprintf(symbol_buf, SYMBOLBUF_MAX,
162                                              "%s+0x%lx", s->name, (long)                                              "%s+0x%"PRIx64, s->name, (uint64_t)
163                                              (addr - s->addr));                                              (addr - s->addr));
164    
165                                  if (offset != NULL)                                  if (offset != NULL)
166                                          *offset = addr - s->addr;                                          *offset = addr - s->addr;
167                                    if (n_argsp != NULL)
168                                            *n_argsp = s->n_args;
169    
170                                  return symbol_buf;                                  return symbol_buf;
171                          }                          }
172    
173                          if (ofs == 0)                          if (addr < s->addr)
174                                  break;                                  highest = ofs - 1;
175                            else
176                          stepsize >>= 1;                                  lowest = ofs + 1;
   
                         /*  Special case for offset 0 (end of search in  
                             the Left direction  */  
                         if (stepsize == 0)  
                                 ofs = 0;  
                         else {  
                                 if (addr < s->addr)  
                                         ofs -= stepsize;  
                                 else  
                                         ofs += stepsize;  
                         }  
177                  }                  }
178          }          }
179    
# Line 190  char *get_symbol_name(struct symbol_cont Line 183  char *get_symbol_name(struct symbol_cont
183    
184    
185  /*  /*
186     *  get_symbol_name():
187     *
188     *  See get_symbol_name_and_n_args().
189     */
190    char *get_symbol_name(struct symbol_context *sc, uint64_t addr, uint64_t *offs)
191    {
192            return get_symbol_name_and_n_args(sc, addr, offs, NULL);
193    }
194    
195    
196    /*
197   *  add_symbol_name():   *  add_symbol_name():
198   *   *
199   *  Add a symbol to the symbol list.   *  Add a symbol to the symbol list.
200   */   */
201  void add_symbol_name(struct symbol_context *sc,  void add_symbol_name(struct symbol_context *sc,
202          uint64_t addr, uint64_t len, char *name, int type)          uint64_t addr, uint64_t len, char *name, int type, int n_args)
203  {  {
204          struct symbol *s;          struct symbol *s;
205    
# Line 210  void add_symbol_name(struct symbol_conte Line 214  void add_symbol_name(struct symbol_conte
214                  exit(1);                  exit(1);
215          }          }
216    
217            if (addr == 0 && strcmp(name, "_DYNAMIC_LINK") == 0)
218                    return;
219    
220          if (name[0] == '\0')          if (name[0] == '\0')
221                  return;                  return;
222    
223          /*  TODO: Maybe this should be optional?  */          /*  TODO: Maybe this should be optional?  */
224          if (name[0] == '$')          if (name[0] == '.' || name[0] == '$')
225                  return;                  return;
226    
227            /*  Quick test-hack:  */
228            if (n_args < 0) {
229                    if (strcmp(name, "strlen") == 0)
230                            n_args = 1;
231                    if (strcmp(name, "strcmp") == 0)
232                            n_args = 2;
233                    if (strcmp(name, "strcpy") == 0)
234                            n_args = 2;
235                    if (strcmp(name, "strncpy") == 0)
236                            n_args = 3;
237                    if (strcmp(name, "strlcpy") == 0)
238                            n_args = 3;
239                    if (strcmp(name, "strlcat") == 0)
240                            n_args = 3;
241                    if (strcmp(name, "strncmp") == 0)
242                            n_args = 3;
243                    if (strcmp(name, "memset") == 0)
244                            n_args = 3;
245                    if (strcmp(name, "memcpy") == 0)
246                            n_args = 3;
247                    if (strcmp(name, "bzero") == 0)
248                            n_args = 2;
249                    if (strcmp(name, "bcopy") == 0)
250                            n_args = 3;
251            }
252    
253          if ((addr >> 32) == 0 && (addr & 0x80000000ULL))          if ((addr >> 32) == 0 && (addr & 0x80000000ULL))
254                  addr |= 0xffffffff00000000ULL;                  addr |= 0xffffffff00000000ULL;
255    
# Line 226  void add_symbol_name(struct symbol_conte Line 259  void add_symbol_name(struct symbol_conte
259                  exit(1);                  exit(1);
260          }          }
261    
262          s->name = strdup(name);          memset(s, 0, sizeof(struct symbol));
263    
264            s->name = symbol_demangle_cplusplus(name);
265    
266          if (s->name == NULL) {          if (s->name == NULL) {
267                  fprintf(stderr, "out of memory\n");                  s->name = strdup(name);
268                  exit(1);                  if (s->name == NULL) {
269                            fprintf(stderr, "out of memory\n");
270                            exit(1);
271                    }
272          }          }
273          s->addr = addr;  
274          s->len  = len;          s->addr   = addr;
275          s->type = type;          s->len    = len;
276            s->type   = type;
277            s->n_args = n_args;
278    
279          sc->n_symbols ++;          sc->n_symbols ++;
280    
# Line 292  void symbol_readfile(struct symbol_conte Line 333  void symbol_readfile(struct symbol_conte
333                  if (type == 't' || type == 'r' || type == 'g')                  if (type == 't' || type == 'r' || type == 'g')
334                          continue;                          continue;
335    
336                  add_symbol_name(sc, addr, len, b4, type);                  add_symbol_name(sc, addr, len, b4, type, -1);
337          }          }
338    
339          fclose(f);          fclose(f);
# Line 367  void symbol_recalc_sizes(struct symbol_c Line 408  void symbol_recalc_sizes(struct symbol_c
408                                      - tmp_array[i].addr;                                      - tmp_array[i].addr;
409                          else                          else
410                                  len = 1;                                  len = 1;
411    
412                          tmp_array[i].len = len;                          tmp_array[i].len = len;
413                  }                  }
414    

Legend:
Removed from v.10  
changed lines
  Added in v.40

  ViewVC Help
Powered by ViewVC 1.1.26