Пример #1
0
Файл: parse.c Проект: lrtfm/math
real compute(F_NODE *formula, SYM_PAIR sym_value_map[], int sym_num)
{
    if (formula->node_type == NODE_TYPE_NUM) {
        return formula->num;
    }

    if (formula->node_type == NODE_TYPE_SYM) {
        return get_sym_value(formula->sym, sym_value_map, sym_num);
    }

    int i;
    real para[MAX_CHILD_NODE];
    if (formula->node_type == NODE_TYPE_FUN) {
        for (i = 0; i < MAX_CHILD_NODE; ++i) {
            if (formula->child[i] == NULL) {
                break;
            }
            para[i] = compute(formula->child[i], sym_value_map, sym_num);
        }

        return formula->fun(i, para);
    }

    // error
    return 0.0;
}
Пример #2
0
static taddr tos_sym_value(symbol *sym,int textbased)
{
  taddr val = get_sym_value(sym);

  /* all sections form a contiguous block, so add section offset */
  if (textbased && sym->type==LABSYM && sym->sec!=NULL)
    val += secoffs[sym->sec->idx];

  return val;
}
Пример #3
0
static int tos_initwrite(section *sec,symbol *sym)
{
  int nsyms = 0;
  int i;

  /* find exactly one .text, .data and .bss section for a.out */
  sections[_TEXT] = sections[_DATA] = sections[_BSS] = NULL;
  secsize[_TEXT] = secsize[_DATA] = secsize[_BSS] = 0;

  for (; sec; sec=sec->next) {
    /* section size is assumed to be in in (sec->pc - sec->org), otherwise
       we would have to calculate it from the atoms and store it there */
    if ((sec->pc - sec->org) > 0 || (sec->flags & HAS_SYMBOLS)) {
      i = get_sec_type(sec);
      if (!sections[i]) {
        sections[i] = sec;
        secsize[i] = (get_sec_size(sec) + SECT_ALIGN - 1) /
                     SECT_ALIGN * SECT_ALIGN;
        sec->idx = i;  /* section index 0:text, 1:data, 2:bss */
      }
      else
        output_error(7,sec->name);
    }
  }

  max_relocs_per_atom = 1;
  secoffs[_TEXT] = 0;
  secoffs[_DATA] = secsize[_TEXT] + balign(secsize[_TEXT],SECT_ALIGN);
  secoffs[_BSS] = secoffs[_DATA] + secsize[_DATA] +
                  balign(secsize[_DATA],SECT_ALIGN);
  /* define small data base as .data+32768 @@@FIXME! */
  sdabase = secoffs[_DATA] + 0x8000;

  /* count symbols */
  for (; sym; sym=sym->next) {
    /* ignore symbols preceded by a '.' and internal symbols */
    if (*sym->name!='.' && *sym->name!=' ') {
      if (!(sym->flags & (VASMINTERN|COMMON)) && sym->type == LABSYM) {
        nsyms++;
        if ((strlen(sym->name) > DRI_NAMELEN) && tos_hisoft_dri)
          nsyms++;  /* extra symbol for long name */
      }
    }
    else {
      if (!strcmp(sym->name," TOSFLAGS")) {
        if (tosflags == 0)  /* not defined by command line? */
          tosflags = (int)get_sym_value(sym);
      }
      sym->flags |= VASMINTERN;
    }
  }
  return no_symbols ? 0 : nsyms;
}
Пример #4
0
static unsigned long aout_convert_rlist(int be,atom *a,int secid,
                                        struct list *rlst,taddr pc,
                          unsigned long (*getrinfo)(rlist *,int,char *,int))
/* convert all of an atom's relocs into a.out relocations */
{
  unsigned long rsize = 0;
  rlist *rl;

  if (a->type == DATA)
    rl = a->content.db->relocs;
  else if (a->type == SPACE)
    rl = a->content.sb->relocs;
  else
    rl = NULL;

  if (!rl)
    return 0;  /* no relocs or not the right atom type */

  do {
    nreloc *r = (nreloc *)rl->reloc;
    symbol *refsym = r->sym;
    taddr val = get_sym_value(refsym);
    taddr add = nreloc_real_addend(r);
#if SDAHACK
    int based = getrinfo(rl,-1,sections[secid]->name,be) != 0;
#endif

    if (refsym->type == LABSYM) {
      /* this is a local relocation */
      int rsecid = refsym->sec->idx;

      aout_addreloclist(rlst,pc+(r->offset>>3),sectype[rsecid],
                        getrinfo(rl,0,sections[secid]->name,be),
                        be);
#if SDAHACK
      if (!based)  /* @@@ 'based' does not really happen in Unix */
#endif
        val += secoffs[rsecid];
      rsize += sizeof(struct relocation_info);
    }
    else if (refsym->type == IMPORT) {
      /* this is an external symbol reference */
      int symidx;

      if ((symidx = aout_findsym(refsym->name,be)) == -1)
        symidx = aout_addsym(refsym->name,0,0,0,N_UNDF|N_EXT,0,be);
      aout_addreloclist(rlst,pc+(r->offset>>3),symidx,
                        getrinfo(rl,1,sections[secid]->name,be),
                        be);
      rsize += sizeof(struct relocation_info);
    }
Пример #5
0
static void aout_symconvert(symbol *sym,int symbind,int syminfo,int be)
/* convert vasm symbol into a.out symbol(s) */
{
  taddr val = get_sym_value(sym);
  taddr size = get_sym_size(sym);
  int ext = (symbind == BIND_GLOBAL) ? N_EXT : 0;
  int type = 0;

  if (TYPE(sym) == TYPE_SECTION) {
    return;   /* section symbols are ignored in a.out! */
  }
  else if (TYPE(sym) == TYPE_FILE) {
    type = N_FN | N_EXT;  /* special case: file name symbol */
    size = 0;
  }
  else {
    if (sym->flags & COMMON) {
      /* common symbol */
      #if 0 /* GNU binutils prefers N_UNDF with val!=0 instead of N_COMM! */
      type = N_COMM | ext;
      #else
      type = N_UNDF | N_EXT;
      #endif
    }
    else if (sym->flags & WEAK) {
      /* weak symbol */
      switch (sym->type) {
        case LABSYM: type=secweak[sym->sec->idx]; break;
        case IMPORT: type=N_WEAKU; break;
        case EXPRESSION: type=N_WEAKA; break;
        default: ierror(0); break;
      }
    }
    else if (sym->sec) {
      /* address symbol */
      type = sectype[sym->sec->idx] | ext;
      val += secoffs[sym->sec->idx];  /* a.out requires to add sec. offset */
    }
    else if (sym->type==EXPRESSION) {
      if (sym->flags & EXPORT) {
        /* absolute symbol */
        type = N_ABS | ext;
      }
      else
        return;  /* ignore local expressions */
    }
    /* @@@ else if (indirect symbols?) {
      aout_addsym(sym->name,0,symbind,0,N_INDR|ext,0,be);
      aout_addsym(sym->indir_name,0,0,0,N_UNDF|N_EXT,0,be);
      return;
    }*/
    else
      ierror(0);
  }

  aout_addsym(sym->name,val,symbind,syminfo,type,0,be);
  if (size) {
    /* append N_SIZE symbol declaring the previous symbol's size */
    aout_addsym(sym->name,size,symbind,syminfo,N_SIZE,0,be);
  }
}