void *emalloc( size_t size ) { void *ptr = NULL; if ( size<0 ) ierror( "emalloc: request for array of negative size.\n" ); if ( !(ptr=malloc(size)) ) ierror( "emalloc: cannot allocate space.\n" ); return ptr; }
static void print_type(FILE *f,symbol *p) { static const char *typename[] = {"???","obj","func","sect","file"}; if(p==NULL) ierror(0); fprintf(f,"type=%s ",typename[TYPE(p)]); } void print_symbol(FILE *f,symbol *p) { if(p==NULL) ierror(0); /* this is usually an error in a cpu-backend, don't crash! */ fprintf(f,"%s ",p->name); if(p->type==LABSYM) fprintf(f,"LAB (0x%llx) ",((unsigned long long)p->pc)&taddrmask); if(p->type==IMPORT) fprintf(f,"IMP "); if(p->type==EXPRESSION) { fprintf(f,"EXPR("); print_expr(f,p->expr); fprintf(f,") "); } if(p->flags&EXPORT) fprintf(f,"EXPORT "); if(p->flags&COMMON) fprintf(f,"COMMON "); if(p->flags&WEAK) fprintf(f,"WEAK "); if(TYPE(p)) print_type(f,p); if(p->size) { fprintf(f,"size="); print_expr(f,p->size); fprintf(f," "); } if(p->align) fprintf(f,"align=%lu ",(unsigned long)p->align); if(p->sec) fprintf(f,"sec=%s ",p->sec->name); } void add_symbol(symbol *p) { hashdata data; p->next=first_symbol; first_symbol=p; data.ptr=p; add_hashentry(symhash,p->name,data); }
static char *string(char *s,dblock **result) { dblock *db=new_dblock(); taddr size; char *p,esc; if(*s!='\"') ierror(0); else s++; p=s; size=0; while(*s&&*s!='\"'){ if(*s=='\\') s=escape(s,&esc); else s++; size++; } db->size=size; db->data=mymalloc(db->size); s=p; p=db->data; while(*s&&*s!='\"'){ if(*s=='\\') s=escape(s,p++); else *p++=*s++; } *result=db; if(*s=!'\"') syntax_error(7); else s++; return s; }
/* * This function has to create the head of a variable * definition, i.e. the label and information for * linkage etc. */ void gen_var_head(FILE *f,struct Var *v){ #ifdef DEBUG_MARK printf("Called gen_var_head(FILE *f,struct Var *v)\n"); #endif switch((v->storage_class) & (STATIC|EXTERN|AUTO|REGISTER)){ case STATIC: #ifdef DEBUG_MARK printf("\tHave to emit static variable head.\n"); #endif emit(f,"L_%ld:\n", zm2l(v->offset)); break; case EXTERN: #ifdef DEBUG_MARK printf("\tHave to emit extern variable head.\n"); #endif if(v->flags&(DEFINED|TENTATIVE)){ emit(f,".EXPORT \t %s\n", v->identifier); emit(f,"%s:\n", v->identifier); } else{ emit(f,".IMPORT \t %s\n", v->identifier); } break; default: #ifdef DEBUG_MARK printf("\tCant generate head, unknown storage class: %d\n", v->storage_class); #else ierror(0); #endif break; } }
bool pattern_match(const char *pat,const char *str) { char c; char *pat1,*pat2; LONG len; bool rc = FALSE; /* convert Unix to AmigaDos pattern */ pat2 = pat1 = alloc(2*strlen(pat)+1); while (c = *pat++) { if (c == '*') { *pat2++ = '#'; *pat2++ = '?'; } else *pat2++ = c; } *pat2 = '\0'; /* tokenize pattern and match it against str */ len = 2*strlen(pat1)+3; pat2 = alloc(len); if (ParsePattern((STRPTR)pat1,(STRPTR)pat2,len) >= 0) { if (MatchPattern((STRPTR)pat2,(STRPTR)str)) rc = TRUE; } else ierror("pattern_match(): ParsePattern() failed for \"%s\"",pat); free(pat2); free(pat1); return (rc); }
void av_update(struct IC *p,bvtype *isused) { int i,j; if((p->z.flags&(VKONST|VAR))==VAR){ i=p->z.v->index; if(p->z.flags&DREFOBJ) i+=vcount-rcount; if(i<0||i>=vcount){ printf("i=%d\n",i);pric2(stdout,p); ierror(0); } if(p->z.flags&DREFOBJ){ if(!(p->z.v->flags&DNOTTYPESAFE)) BCLR(isused,i); }else{ if(ISSCALAR(p->z.v->vtyp->flags)||(p->code==ASSIGN&&zmeqto(p->q2.val.vmax,szof(p->z.v->vtyp)))) BCLR(isused,i); } /* bei Zuweisung an p wird *p aktiv */ if(i<rcount) BSET(isused,i+vcount-rcount); } for(j=0;j<p->use_cnt;j++){ i=p->use_list[j].v->index; if(p->use_list[j].flags&DREFOBJ) i+=vcount-rcount; if(i<0||i>=vcount) continue; BSET(isused,i); } }
static void print_source_line(FILE *f) { static char *buf = NULL; char c,*e,*p,*q; int l; /* get an error line buffer only once on demand */ if (buf == NULL) buf = mymalloc(MAXLINELENGTH); p = cur_src->text; q = buf; e = buf + MAXLINELENGTH - 1; l = cur_src->line; do { c = *p++; if (c=='\n' || c=='\r') { if (*p == ((c=='\n') ? '\r' : '\n')) p++; if (--l == 0) { /* terminate error line in buffer and print it */ *q = '\0'; fprintf(f,">%s\n",buf); return; } q = buf; /* next line, start to fill buffer from the beginning */ } else if (q < e) *q++ = c; } while (*p); ierror(0); /* line doesn't exist */ }
thuge huge_from_mem(int be,void *src,size_t size) { uint8_t *s = src; thuge r; if (size > HUGEBITS/8) ierror(0); if (be) { if ((int8_t)*s < 0) r.hi = r.lo = ~0; else r.hi = r.lo = 0; while (size--) { r = hshl(r,8); r.lo |= *s++; } } else { s += size; if ((int8_t)*(s-1) < 0) r.hi = r.lo = ~0; else r.hi = r.lo = 0; while (size--) { r = hshl(r,8); r.lo |= *(--s); } } return r; }
static int vobj_targetlink(struct GlobalVars *gv,struct LinkedSection *ls, struct Section *s) /* returns 1, if target requires the combination of the two sections, */ /* returns -1, if target doesn't want to combine them, */ /* returns 0, if target doesn't care - standard linking rules are used. */ { ierror("vobj_targetlink(): Impossible to link vobjects"); return (0); }
void print_vi(void) /* Druckt vilist und testet Konsistenz */ { int i; printf("\nprint_vi()\n"); for(i=0;i<vcount;i++){ if(!vilist[i]||(i<rcount&&vilist[i]->index!=i)) ierror(0); printf("%3d: %s\n",i,vilist[i]->identifier); } }
void tos_writerelocs(struct GlobalVars *gv,FILE *f, struct LinkedSection **sections) { const char *fn = "tos_writerelocs(): "; int i; struct Reloc *rel; struct RelocInsert *ri; unsigned long lastoffs = 0; for (i=0; i<3; i++) { if (sections[i]) { sort_relocs(§ions[i]->relocs); for (rel=(struct Reloc *)sections[i]->relocs.first; rel->n.next!=NULL; rel=(struct Reloc *)rel->n.next) { if (ri = rel->insert) { if (rel->rtype!=R_ABS || ri->bpos!=0 || ri->bsiz!=32) { error(32,fff_ataritos.tname,reloc_name[rel->rtype], (int)ri->bpos,(int)ri->bsiz,ri->mask, sections[i]->name,rel->offset); continue; } } else continue; if (!lastoffs) { /* first relocation offset is 32 bits, the rest are bytes! */ fwrite32be(f,sections[i]->base + rel->offset); } else { long diff = (sections[i]->base + rel->offset) - lastoffs; if (diff < 0) { ierror("%snegative offset difference: " "%s(0x%08lx)+0x%08lx - 0x%08lx",fn,sections[i]->name, sections[i]->base,rel->offset,lastoffs); } while (diff > 254) { fwrite8(f,1); diff -= 254; } fwrite8(f,(uint8_t)diff); } lastoffs = sections[i]->base + rel->offset; } } } if (!lastoffs) { /* not a single relocation written - write 0-word */ fwrite32be(f,0); } else fwrite8(f,0); }
/* walks through a clist and numbers variables whose addresses are contained; if pass==-1, index is set to -1, if pass==0, index is set, otherwise vilist clcnt is used as index-counter in pass 0 */ void num_clist_refs(int pass,struct Typ *t,struct const_list *cl) { /*FIXME: bei Aufrufen auch auf locale, nicht USEDASDEST|USEDASADDR */ int i;zmax sz; if(ISARRAY(t->flags)){ for(sz=l2zm(0L);!zmleq(t->size,sz)&&cl;sz=zmadd(sz,l2zm(1L)),cl=cl->next){ if(!cl->other){ierror(0);return;} num_clist_refs(pass,t->next,cl->other); } return; } if(ISUNION(t->flags)){ num_clist_refs(pass,(*t->exact->sl)[0].styp,cl); return; } if(ISSTRUCT(t->flags)&&!cl->tree){ struct Typ *st; for(i=0;i<t->exact->count&&cl;i++){ st=(*t->exact->sl)[i].styp; if(!(*t->exact->sl)[i].identifier) ierror(0); if((*t->exact->sl)[i].identifier[0]){ if(!cl->other) ierror(0); num_clist_refs(pass,st,cl->other); cl=cl->next; } } return; } if(cl->tree&&(cl->tree->o.flags&VARADR)){ struct Var *v=cl->tree->o.v; if(pass==-1){ v->index=-1; }else if(pass==0){ if(v->index<0) {v->index=clcnt++;v->inr=inr;} }else{ if(v->index<0||v->index>=vcount-rcount) ierror(0); vilist[v->index]=v; } } }
isis() { BYTE opcode; if ((WORD)savepc != 0x41) /* not an ISIS-II call? */ { monitor(); /* must be an MDS monitor call */ return; } switch(savebc & 0xff) /* it's an ISIS-II trap - do the right thing */ { case 0: iopen((OBLK *)savede); /* OPEN call */ break; case 1: iclose((CBLK *)savede); /* CLOSE call */ break; case 2: idelete((DBLK *)savede); /* DELETE call */ break; case 3: iread((RBLK *)savede); /* READ call */ break; case 4: iwrite((WBLK *)savede); /* WRITE call */ break; case 5: iseek((SBLK *)savede); /* SEEK call */ break; case 6: iload((LBLK *)savede); /* LOAD call */ break; case 7: irename((RNBLK *)savede); /* RENAME call */ break; case 9: cleanup(); break; case 11: irescan((RSBLK *)savede); /* RESCAN call */ break; case 12: /* ERROR call */ ierror((EBLK *)savede); break; case 14: /* SPATH call */ ispath((SPBLK *)savede); break; default: print("\r\nIllegal ISIS-II function call "); phexw(savebc); print("\r\n"); break; } }
bool MenuWindow::Valid(void) const { if (! m_pFullMenuBar) { ierror(STR_NO_FULL_MENU_BAR); return false; } if (! m_pHiddenMenuBar) { ierror(STR_NO_HIDDEN_MENU_BAR); return false; } if (! m_pMenuView) { ierror(STR_NO_MENU_VIEW); return false; } if (! m_pStatusView) { ierror(STR_NO_STATUS_VIEW); return false; } return true; }
static int aout_getbind(symbol *sym) { if (sym->flags & WEAK) return BIND_WEAK; else if (sym->type!=IMPORT && !(sym->flags & EXPORT)) return BIND_LOCAL; else if ((sym->type!=IMPORT && (sym->flags & EXPORT)) || (sym->type==IMPORT && (sym->flags & COMMON))) return BIND_GLOBAL; else ierror(0); return -1; }
static struct Symbol *i386_dynentry(struct GlobalVars *gv,DynArg a,int etype) /* Create an entry into .got/.plt/.bss for the referenced symbol. */ { struct Symbol *entry_sym = NULL; struct Section *sec; char *bssname; switch (etype) { case GOT_ENTRY: case GOT_LOCAL: /* .got has 12 bytes reserved at the beginning, is writable, a new entry occupies 4 bytes. */ sec = elf32_dyntable(gv,12,12,ST_DATA,SF_ALLOC, SP_READ|SP_WRITE,GOT_ENTRY); entry_sym = elf32_pltgotentry(gv,sec,a,SYMI_OBJECT,4,4,etype); break; case PLT_ENTRY: /* .plt has 16 bytes reserved at the beginning, is executable, a new entry occupies another 16 bytes. */ sec = elf32_dyntable(gv,16,16,ST_CODE,SF_ALLOC, SP_READ|SP_EXEC,PLT_ENTRY); entry_sym = elf32_pltgotentry(gv,sec,a,SYMI_FUNC,16,16,PLT_ENTRY); break; case BSS_ENTRY: /* @@@ */ ierror("i386_dynentry(): BSS_ENTRY not yet written"); break; default: ierror("i386_dynentry(): illegal entrytype: %d",etype); break; } return entry_sym; }
/* replace instruction by one with encoding enc */ static int replace(int c,int enc) { int i=c+1; while(!strcmp(mnemonics[c].name,mnemonics[i].name)){ if(mnemonics[i].ext.encoding==enc){ c=i; break; } i++; } if(c!=i) ierror(0); return c; }
void error(error_id id, void * data) { switch (id) { case UNEXPECTED_EOF: fprintf(stderr, "Error: Unexpected end of file.\n"); break; case EXPECTED_COLON: fprintf(stderr, "Error: Expected ':' after '%c'.\n", *((char*)data)); break; case EXPECTED_LBRACKET: fprintf(stderr, "Error: Expected '[' after '%c'.\n", *((char*)data)); break; case EXPECTED_EQUALS: fprintf(stderr, "Error: Expected '=' after '%s'.\n", (char*)data); break; case EXPECTED_LBRACE: fprintf(stderr, "Error: Expected '{' after 'contents='.\n"); break; case BAD_BRANCH_FLAG: fprintf(stderr, "Error: Flag '%s' is invalid for branches.\n", (char*)data); break; case BAD_FILE_FLAG: fprintf(stderr, "Error: Flag '%s' is invalid for files.\n", (char*)data); break; case BAD_INDIRECT_FLAG: fprintf(stderr, "Error: Flag '%s' is invalid for indirects.\n", (char*)data); break; case BAD_BRANCH_FIELD: fprintf(stderr, "Error: Field '%s' is invalid for branches.\n", (char*)data); break; case BAD_FILE_FIELD: fprintf(stderr, "Error: Field '%s' is invalid for files.\n", (char*)data); break; case BAD_INDIRECT_FIELD: fprintf(stderr, "Error: Field '%s' is invalid for indirects.\n", (char*)data); break; case MAX_STR_SIZE_EXCEEDED: fprintf(stderr, "Error: String '%s' exceeds maximium string size.\n", (char*)data); break; case STRAY_NODE: fprintf(stderr, "Error: Stray node '%s'.\n", (char*)data); break; case UNRECOGNIZED_TYPE: fprintf(stderr, "Error: Unrecognized type '%c'.\n", *((char*)data)); break; default: ierror(BAD_ERROR, "error"); } exit(-1); }
static int operand_code(operand *p) { if(!p) return 0; if(p->type==OP_REG) return p->basereg; if(p->type==OP_REGIND) return 4+p->basereg; if(p->type==OP_ABS) return 8; if(p->type==OP_IMM32) return 9; ierror(0); }
static size_t oplen(int op) { if(op<=EN_MEMDISP16) return 2; else if(op<=EN_ARITHI32) return 4; else if(op<=EN_VARITHI48) return 6; else if(op<=EN_ADDCMPB64) return 8; else if(op<=EN_VARITHI80) return 10; ierror(0); }
static void resolve_section(section *sec) { atom *p; int done,pass=0; taddr size; do { done=1; if (++pass>=MAXPASSES) { general_error(7,sec->name); break; } if(DEBUG) printf("resolve_section(%s) pass %d\n",sec->name,pass); sec->pc=sec->org; for(p=sec->first; p; p=p->next) { sec->pc=(sec->pc+p->align-1)/p->align*p->align; cur_src=p->src; cur_src->line=p->line; #ifdef HAVE_CPU_OPTS if(p->type==OPTS) { cpu_opts(p->content.opts); } else #endif if(p->type==LABEL) { symbol *label=p->content.label; if(label->type!=LABSYM) ierror(0); if(label->pc!=sec->pc) { if(DEBUG) printf("changing label %s from %lu to %lu\n",label->name, (unsigned long)label->pc,(unsigned long)sec->pc); done=0; label->pc=sec->pc; } } size=atom_size(p,sec,sec->pc); #ifdef CHECK_ATOMSIZE if(size!=p->lastsize) { if(DEBUG) printf("changed size of atom type %d at %lu from %ld to %ld\n", p->type,(unsigned long)sec->pc,(long)p->lastsize,(long)size); done=0; p->lastsize=size; } #endif sec->pc+=size; } } while(errors==0&&!done); }
void av_change(struct IC *p,bvtype *use,bvtype *def) /* Berechnet die Aenderungen, die sich durch IC p an use und def ergeben. */ { int i,j,n=-1; int g1,g2; /* Wenn eine Quelle==Ziel, dann wird dadurch kein neuer use erzeugt, */ /* um z.B. unbenutzte Induktionsvariablen in Schleifen zu eliminieren. */ g1=compare_objs(&p->q1,&p->z,p->typf); g2=compare_objs(&p->q2,&p->z,p->typf); if(!g1&&(p->q1.flags&(VAR|DREFOBJ))==VAR) n=p->q1.v->index; if(!g2&&(p->q2.flags&(VAR|DREFOBJ))==VAR) n=p->q2.v->index; for(j=0;j<p->use_cnt;j++){ i=p->use_list[j].v->index; if(p->use_list[j].flags&DREFOBJ) i+=vcount-rcount; if(i>=vcount) continue; if(i!=n&&!BTST(def,i)) BSET(use,i); } /* Ein Wert wird nicht zerstoert, wenn es kein elementarer Typ ist und */ /* die Groesse kleiner als die Variable (steht in alle solchen ICs in */ /* q2.val.max. */ if((p->z.flags&(VAR|DREFOBJ))==VAR&&(ISSCALAR(p->z.v->vtyp->flags)||p->z.v->vtyp->flags==0||zmeqto(p->q2.val.vmax,szof(p->z.v->vtyp)))){ i=p->z.v->index; if(i>=vcount) ierror(0); if(g1&&g2&&!BTST(use,i)) BSET(def,i); /* Wenn p geaendert wird, wird auch *p geaendert */ if(i<rcount&&!BTST(def,i+vcount-rcount)) BSET(use,i+vcount-rcount); } if((p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)&&g1&&g2&&!(p->z.v->flags&DNOTTYPESAFE)){ i=p->z.v->index+vcount-rcount; if(i>=vcount) ierror(0); if(!BTST(use,i)) BSET(def,i); } }
static taddr new_stabstr(char *name) { section *str; taddr index; dblock *db; if (!(str = find_section(stabstrname,stabstrattr))) ierror(0); index = str->pc; db = new_dblock(); db->size = strlen(name) + 1; db->data = name; add_atom(str,new_data_atom(db,1)); return index; }
bool checkrange(lword val,bool sign,int size) /* Checks if 'val' (signed or unsigned) fits into 'size' bits. Returns FALSE when 'val' is out of range! */ { if (size) { lword min = -(1LL<<(size-1)); lword max = sign ? ((1LL<<(size-1))-1LL) : ((1LL<<size)-1LL); if (val<min || val>max) return FALSE; return TRUE; } ierror("checkrange(): size==0 (val=%lld)\n",val); return FALSE; /* size==0 is illegal */ }
static void stab_entry(char *name,int type,int othr,int desc,char *s) { section *stabs; if (!(stabs = find_section(stabname,stabattr))) { section *str; dblock *db; stabs = new_section(stabname,stabattr,4); if (!(str = find_section(stabstrname,stabstrattr))) { str = new_section(stabstrname,stabstrattr,1); } else { if (str->pc != 0) ierror(0); } /* first byte of .stabstr is 0 */ add_atom(str,new_space_atom(number_expr(1),1,0)); /* compilation unit header has to be patched by output module */ new_stabstr(getfilename()); db = new_dblock(); db->size = 12; db->data = mymalloc(12); add_atom(stabs,new_data_atom(db,1)); } add_const_datadef(stabs,name?new_stabstr(name):0,32,1); add_const_datadef(stabs,type,8,1); add_const_datadef(stabs,othr,8,1); add_const_datadef(stabs,desc,16,1); if (s) { operand *op = new_operand(); int len = oplen(skip_operand(s),s); if (parse_operand(s,len,op,DATA_OPERAND(32))) { atom *a = new_datadef_atom(32,op); a->align = 1; add_atom(stabs,a); } else syntax_error(8); } else add_atom(stabs,new_space_atom(number_expr(4),1,0)); /* no value */ }
static void ifexp(char *s,int c) { taddr val = parse_constexpr(&s); int b; switch (c) { case 0: b = val == 0; break; case 1: b = val != 0; break; case 2: b = val > 0; break; case 3: b = val >= 0; break; case 4: b = val < 0; break; case 5: b = val <= 0; break; default: ierror(0); break; } cond[++clev] = b; eol(s); }
static void vobj_readconv(struct GlobalVars *gv,struct LinkFile *lf) { if (lf->type == ID_LIBARCH) { if (ar_init(&ai,(char *)lf->data,lf->length,lf->filename)) { while (ar_extract(&ai)) { lf->objname = allocstring(ai.name); vobj_read(gv,lf,(uint8_t *)ai.data); } } else ierror("vobj_readconv(): archive %s corrupted since last access", lf->pathname); } else { lf->objname = lf->filename; vobj_read(gv,lf,lf->data); } }
void ierror(ierror_id id, void * data) { switch (id) { case BAD_ERROR: fprintf(stderr, "Internal Error: Bad %s.\n", (char*)data); break; case BAD_I_IN_PTR_CALC: fprintf(stderr, "Internal Error: The 'i' value '%d' given to 'calc_f300_ptr' is invalid.\n", *((int*)data)); case BAD_TBL_IN_PTR_CALC: fprintf(stderr, "Internal Error: The 'tbl' value '%p' given to 'calc_f300_ptr' is invalid.\n", data); break; default: ierror(BAD_ERROR, "internal error (sup dawg)"); break; } exit(-2); }
static void imm(struct DisasmPara_PPC *dp,ppc_word in,int uimm,int type,int hex) /* Generate immediate instruction operand. */ /* type 0: D-mode, D,A,imm */ /* type 1: S-mode, A,S,imm */ /* type 2: S/D register is ignored (trap,cmpi) */ /* type 3: A register is ignored (li) */ { int i = (int)(in & 0xffff); dp->type = PPCINSTR_IMM; if (!uimm) { if (i > 0x7fff) i -= 0x10000; } else dp->flags |= PPCF_UNSIGNED; dp->displacement = i; switch (type) { case 0: sprintf(dp->operands,"%s, %s, %d",regnames[(int)PPCGETD(in)],regnames[(int)PPCGETA(in)],i); break; case 1: if (hex) sprintf(dp->operands,"%s, %s, 0x%.4X",regnames[(int)PPCGETA(in)],regnames[(int)PPCGETD(in)],i); else sprintf(dp->operands,"%s, %s, %d",regnames[(int)PPCGETA(in)],regnames[(int)PPCGETD(in)],i); break; case 2: sprintf(dp->operands,"%s, %d",regnames[(int)PPCGETA(in)],i); break; case 3: if (hex) sprintf(dp->operands,"%s, 0x%.4X",regnames[(int)PPCGETD(in)],i); else sprintf(dp->operands,"%s, %d",regnames[(int)PPCGETD(in)],i); break; default: ierror("imm(): Wrong type"); break; } }
int writetaddr(struct GlobalVars *gv,void *p,lword d) { bool be = fff[gv->dest_format]->endianess == _BIG_ENDIAN_; switch (fff[gv->dest_format]->addr_bits) { case 16: write16(be,p,(uint16_t)d); return 2; case 32: write32(be,p,(uint32_t)d); return 4; case 64: write64(be,p,(uint64_t)d); return 8; default: ierror("writetaddr(): target address has %d bits", (int)fff[gv->dest_format]->addr_bits); break; } return 0; }