[insert project logo here (125x200px max)] Navigator Mailinglists Please report any errors or ommissions you find to our `Help' mailinglist, or post a message in the Forums. Copyright and Licensing Information Snap is (c) Jonathan T. Moore, 1999-2002 and licensed under the GNU General Public License (GPL). All other parts of Splash are (c) Willem de Bruijn, 2002-2003 and licensed under the BSD Open Source License. All sourcecode is made publicly available. Acknowledgement Splash and the Splash website are hosted by SourceForge.net |
Splash - DocumentationSNMP Plus a Lightweight API for SNAP Handlingsnap-1.1-wjdb/utils/labels.cGo to the documentation of this file.00001 /* snap-1.0. Copyright (C) 2000 by Jonathan T. Moore and Michael Hicks. 00002 * 00003 * labels.c : routines used by the assembler to keep track of labels 00004 * and fill in their values with offsets 00005 * 00006 * $Id: labels.c,v 1.1 2002/12/22 16:20:16 wdebruij Exp $ 00007 */ 00008 00009 #include <assert.h> 00010 #include <stdio.h> 00011 #include <stdlib.h> 00012 #include <string.h> 00013 #include "../lib/io.h" 00014 #include "../lib/bytecode.h" 00015 #include "../lib/d_printf.h" 00016 #include "../lib/dyncheck.h" 00017 00018 /******************* local functions and data *********************/ 00019 00020 typedef struct { 00021 char *name; 00022 void *where; 00023 } label_mapping_t; 00024 00025 #define MAX_NUM_LABELS 100 00026 00027 static label_mapping_t label_def_map[MAX_NUM_LABELS]; 00028 static int label_def_map_idx = 0; 00029 static label_mapping_t label_use_map[MAX_NUM_LABELS]; 00030 static int label_use_map_idx = 0; 00031 00032 /* associates the label with the current pc */ 00033 static void register_label(label_mapping_t map[], 00034 int idx, 00035 char *labname, 00036 void *where) { 00037 assert(where != NULL); 00038 assert(labname != NULL); 00039 if (idx >= MAX_NUM_LABELS) { 00040 fprintf(stderr,"Exceeded static size of label map (%d)!\n", 00041 MAX_NUM_LABELS); 00042 exit(1); 00043 } 00044 map[idx].name = labname; 00045 map[idx].where = where; 00046 d_printf(100,"registered label %s at addr %x in table %x\n", 00047 labname,(unsigned int)where,(unsigned int)map); 00048 } 00049 00050 static char *find_label(label_mapping_t map[], int idx, void *where) { 00051 int i; 00052 for (i=0; i<idx; i++) { 00053 if (map[i].where == where) { 00054 return map[i].name; 00055 } 00056 } 00057 return NULL; /* not found */ 00058 } 00059 00060 static void *find_where(label_mapping_t map[], int idx, char *label) { 00061 int i; 00062 for (i=0; i<idx; i++) { 00063 if (!strcmp(map[i].name, label)) { 00064 return map[i].where; 00065 } 00066 } 00067 return NULL; /* not found */ 00068 } 00069 00070 /************************ exported functions *************************/ 00071 00072 void register_label_def(char *labname, 00073 void *where) { 00074 register_label(label_def_map,label_def_map_idx,labname,where); 00075 label_def_map_idx++; 00076 } 00077 00078 void register_label_use(char *labname, 00079 void *where) { 00080 register_label(label_use_map,label_use_map_idx,labname,where); 00081 label_use_map_idx++; 00082 } 00083 00084 static int calc_offs(char *label, instr_t *startpc) { 00085 instr_t *def_pc; 00086 00087 assert(startpc != NULL); 00088 00089 /* find the label's definition */ 00090 def_pc = (instr_t *)find_where(label_def_map, label_def_map_idx, label); 00091 if (def_pc == NULL) { 00092 fprintf(stderr,"label %s, is undefined\n", label); 00093 exit(1); 00094 } 00095 /* patch it */ 00096 return (int)(def_pc - startpc); 00097 } 00098 00099 static void fill_value_label(value_t *v, char *label, instr_t *startpc) { 00100 int ofs; 00101 00102 assert(v != NULL); 00103 assert(startpc != NULL); 00104 00105 ofs = calc_offs(label,startpc); 00106 00107 /* store in the argument for the instruction */ 00108 SET_INT(*v,GET_INT(*v) + ofs); 00109 d_printf(100,"patched label %s at addr %x; ofs = %d, val = %d\n", 00110 label,(unsigned int)v,ofs,GET_INT(*v)); 00111 assert(GET_INT(*v) >= 0); 00112 } 00113 00114 static void fill_literal_label(instr_t *pc, char *label, instr_t *startpc) { 00115 int ofs; 00116 00117 assert(pc != NULL); 00118 assert(startpc != NULL); 00119 00120 GET_LIT(ofs,INTV,*pc); 00121 ofs += calc_offs(label,startpc); 00122 00123 /* store in the argument for the instruction */ 00124 SET_LIT(*pc,INTV,ofs); 00125 d_printf(100,"patched label %s at pc %x; val = %d\n", 00126 label,(unsigned int)pc,ofs); 00127 } 00128 00129 /* patch each instruction in the packet. It is assumed that the 00130 current pc of the packet is at the end of the code. */ 00131 void patch_jumps(packet_t *p) { 00132 instr_t *cur_pc; 00133 value_t *cur_v; 00134 char *label; 00135 00136 /* patch jumps in the code portion */ 00137 for (cur_pc = p->code_min; cur_pc < p->pc; cur_pc++) 00138 switch (GET_OP(*cur_pc)) { 00139 case JI: 00140 case BNE: 00141 case BEZ: 00142 case PUSH: 00143 #ifdef SMALL_INSTRS 00144 case PINT: 00145 case EQINT: 00146 case NQINT: 00147 case PADDR: 00148 case EQADR: 00149 case NQADR: 00150 case PTUP: 00151 case EQTUP: 00152 case NQTUP: 00153 case PEXC: 00154 case EQEXC: 00155 case NQEXC: 00156 case PSTR: 00157 case EQSTR: 00158 case NQSTR: 00159 #endif 00160 label = find_label(label_use_map,label_use_map_idx,cur_pc); 00161 if (label != NULL) 00162 fill_literal_label(cur_pc,label,p->code_min); 00163 break; 00164 00165 default: 00166 assert(find_label(label_use_map,label_use_map_idx,cur_pc)==NULL); 00167 break; 00168 } 00169 00170 /* now in the stack */ 00171 for (cur_v = p->stack_min; cur_v < p->sp; cur_v++) { 00172 label = find_label(label_use_map,label_use_map_idx,cur_v); 00173 if (label != NULL) 00174 fill_value_label(cur_v,label,p->code_min); 00175 } 00176 } |