[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

SourceForge.net Logo

osi-open source certified logo

Splash - Documentation

SNMP Plus a Lightweight API for SNAP Handling

Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

snap-1.1-wjdb/utils/labels.c

Go 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 }