Ensure we null-terminate the string we copy at the start of

m68k_reg_parse.
This commit is contained in:
Michael Tiemann 1991-11-24 17:24:52 +00:00
parent 5bcc23e3b2
commit 865a2edf64

View file

@ -314,8 +314,11 @@ struct m68k_it {
} reloc[5]; /* Five is enough??? */ } reloc[5]; /* Five is enough??? */
}; };
#define cpu_of_arch(x) ((x) & m68000up)
#define float_of_arch(x) ((x) & mfloat)
#define mmu_of_arch(x) ((x) & mmmu)
static struct m68k_it the_ins; /* the instruction being assembled */ static struct m68k_it the_ins; /* the instruction being assembled */
static enum m68k_architecture max_arch_this_insn;
/* Macros for adding things to the m68k_it struct */ /* Macros for adding things to the m68k_it struct */
@ -412,14 +415,7 @@ static void s_proc();
#endif /* __STDC__ */ #endif /* __STDC__ */
static enum m68k_architecture current_architecture = m68020 static enum m68k_architecture current_architecture = 0;
#ifndef NO_68881
| m68881
#endif
#ifndef NO_68851
| m68851
#endif
;
/* BCC68000 is for patching in an extra jmp instruction for long offsets /* BCC68000 is for patching in an extra jmp instruction for long offsets
on the 68000. The 68000 doesn't support long branches with branchs */ on the 68000. The 68000 doesn't support long branches with branchs */
@ -558,9 +554,16 @@ register char **ccp;
} /* need prefix */ } /* need prefix */
#endif #endif
for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN && *q != 0; ++p, ++q) { for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q)
*p = mklower(*q); {
} /* downcase */ if (*q == 0)
{
*p = 0;
break;
}
else
*p = mklower(*q);
} /* downcase */
switch(c[0]) { switch(c[0]) {
case 'a': case 'a':
@ -835,38 +838,37 @@ register struct m68k_op *opP;
if(i!=FAIL && (*str=='/' || *str=='-')) { if(i!=FAIL && (*str=='/' || *str=='-')) {
opP->mode=REGLST; opP->mode=REGLST;
return get_regs(i,str,opP); return(get_regs(i,str,opP));
} }
if ((stmp=strchr(str,'@')) != '\0') { if ((stmp=strchr(str,'@')) != '\0') {
opP->con1=add_exp(str,stmp-1); opP->con1=add_exp(str,stmp-1);
if(stmp==strend) { if(stmp==strend) {
opP->mode=AINDX; opP->mode=AINDX;
return OK; return(OK);
} }
if ((current_architecture & m68020up) == 0) {
return(FAIL);
} /* if target is not a '20 or better */
stmp++; stmp++;
if(*stmp++!='(' || *strend--!=')') { if(*stmp++!='(' || *strend--!=')') {
opP->error="Malformed operand"; opP->error="Malformed operand";
return FAIL; return(FAIL);
} }
i=try_index(&stmp,opP); i=try_index(&stmp,opP);
opP->con2=add_exp(stmp,strend); opP->con2=add_exp(stmp,strend);
if (i == FAIL) { if (i == FAIL) {
opP->mode=AMIND; opP->mode=AMIND;
if (max_arch_this_insn < m68020) {
max_arch_this_insn = m68020;
} /* bump arch */
} else { } else {
opP->mode=APODX; opP->mode=APODX;
if (max_arch_this_insn < m68020) {
max_arch_this_insn = m68020;
} /* bump arch */
} }
return OK; return(OK);
} /* if there's an '@' */ } /* if there's an '@' */
opP->mode=ABSL; opP->mode = ABSL;
opP->con1=add_exp(str,strend); opP->con1 = add_exp(str,strend);
return OK; return(OK);
} /* not a register, not exactly a register, or no '@' */ } /* not a register, not exactly a register, or no '@' */
opP->reg=i; opP->reg=i;
@ -957,89 +959,84 @@ register struct m68k_op *opP;
} }
/* We've now got offset) offset,reg) or reg) */ /* We've now got offset) offset,reg) or reg) */
if(*str=='\0') { if (*str == '\0') {
/* Th-the-thats all folks */ /* Th-the-thats all folks */
if(opP->reg==FAIL) opP->mode=AINDX; /* Other form of indirect */ if (opP->reg == FAIL) opP->mode = AINDX; /* Other form of indirect */
else if(opP->ireg==FAIL) opP->mode=AOFF; else if(opP->ireg == FAIL) opP->mode = AOFF;
else opP->mode=AINDX; else opP->mode = AINDX;
return OK; return(OK);
} }
/* Next thing had better be another @ */ /* Next thing had better be another @ */
if(*str!='@' || str[1]!='(') { if(*str!='@' || str[1]!='(') {
opP->error="junk after indirect"; opP->error = "junk after indirect";
return FAIL; return(FAIL);
} }
if ((current_architecture & m68020up) == 0) {
return(FAIL);
} /* if target is not a '20 or better */
str+=2; str+=2;
if(opP->ireg!=FAIL) {
opP->mode=APRDX; if(opP->ireg != FAIL) {
opP->mode = APRDX;
if (max_arch_this_insn < m68020) {
max_arch_this_insn = m68020; i = try_index(&str, opP);
} /* bump arch */ if (i != FAIL) {
opP->error = "Two index registers! not allowed!";
i=try_index(&str,opP); return(FAIL);
if(i!=FAIL) {
opP->error="Two index registers! not allowed!";
return FAIL;
} }
} else } else {
i=try_index(&str,opP); i = try_index(&str, opP);
}
if (i == FAIL) { if (i == FAIL) {
char *beg_str; char *beg_str;
beg_str=str; beg_str = str;
for(i=1;i;) {
for (i = 1; i; ) {
switch(*str++) { switch(*str++) {
case '\0': case '\0':
opP->error="Missing )"; opP->error="Missing )";
return FAIL; return(FAIL);
case ',': i=0; break; case ',': i=0; break;
case '(': i++; break; case '(': i++; break;
case ')': --i; break; case ')': --i; break;
} }
} }
opP->con2=add_exp(beg_str,str-2); opP->con2=add_exp(beg_str,str-2);
if(str[-1]==',') {
if(opP->ireg!=FAIL) { if (str[-1] == ',') {
opP->error="Can't have two index regs"; if (opP->ireg != FAIL) {
return FAIL; opP->error = "Can't have two index regs";
return(FAIL);
} }
i=try_index(&str,opP);
if(i==FAIL) { i = try_index(&str, opP);
opP->error="malformed index reg";
return FAIL; if (i == FAIL) {
opP->error = "malformed index reg";
return(FAIL);
} }
opP->mode=APODX;
if (max_arch_this_insn < m68020) { opP->mode = APODX;
max_arch_this_insn = m68020; } else if (opP->ireg != FAIL) {
} /* bump arch */ opP->mode = APRDX;
} else if(opP->ireg!=FAIL) {
opP->mode=APRDX;
if (max_arch_this_insn < m68020) {
max_arch_this_insn = m68020;
} /* bump arch */
} else { } else {
opP->mode=AMIND; opP->mode = AMIND;
if (max_arch_this_insn < m68020) {
max_arch_this_insn = m68020;
} /* bump arch */
} }
} else { } else {
opP->mode=APODX; opP->mode = APODX;
if (max_arch_this_insn < m68020) {
max_arch_this_insn = m68020;
} /* bump arch */
} }
if(*str!='\0') { if(*str!='\0') {
opP->error="Junk after indirect"; opP->error="Junk after indirect";
return FAIL; return FAIL;
} }
return OK; return(OK);
} } /* m68k_ip_op() */
/* /*
* *
@ -1206,8 +1203,6 @@ char *instring;
LITTLENUM_TYPE words[6]; LITTLENUM_TYPE words[6];
LITTLENUM_TYPE *wordp; LITTLENUM_TYPE *wordp;
max_arch_this_insn = m68000;
if (*instring == ' ') if (*instring == ' ')
instring++; /* skip leading whitespace */ instring++; /* skip leading whitespace */
@ -1253,7 +1248,7 @@ char *instring;
} }
} }
opsfound=opP- &the_ins.operands[0]; opsfound = opP - &the_ins.operands[0];
/* This ugly hack is to support the floating pt opcodes in their standard form */ /* This ugly hack is to support the floating pt opcodes in their standard form */
/* Essentially, we fake a first enty of type COP#1 */ /* Essentially, we fake a first enty of type COP#1 */
@ -1272,13 +1267,13 @@ char *instring;
/* We've got the operands. Find an opcode that'll accept them */ /* We've got the operands. Find an opcode that'll accept them */
for (losing = 0; ; ) { for (losing = 0; ; ) {
/* if we didn't get the right number of ops, or either /* if we didn't get the right number of ops,
the modes of our args or this op line itself are out or we have no common model with this pattern
of order... */ then reject this pattern. */
if ((opsfound != opcode->m_opnum) if (opsfound != opcode->m_opnum
|| ((max_arch_this_insn > current_architecture) || ((opcode->m_arch & current_architecture) == 0)) {
|| (opcode->m_arch > current_architecture))) {
++losing; ++losing;
} else { } else {
@ -1291,8 +1286,10 @@ char *instring;
it belongs to. I hope this makes sense. */ it belongs to. I hope this makes sense. */
switch(*s) { switch(*s) {
case '!': case '!':
if(opP->mode==MSCR || opP->mode==IMMED || if (opP->mode == MSCR || opP->mode == IMMED
opP->mode==DREG || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST) || opP->mode == DREG || opP->mode == AREG
|| opP->mode == AINC || opP->mode == ADEC
|| opP->mode == REGLST)
losing++; losing++;
break; break;
@ -1429,13 +1426,13 @@ char *instring;
if (opP->mode != MSCR if (opP->mode != MSCR
|| opP->reg < USP || opP->reg < USP
|| opP->reg > URP || opP->reg > URP
|| (current_architecture & m68000up) < m68010 /* before 68010 had none */ || cpu_of_arch(current_architecture) < m68010 /* before 68010 had none */
|| ((current_architecture & m68020up) == 0 || (cpu_of_arch(current_architecture) < m68020
&& opP->reg != SFC && opP->reg != SFC
&& opP->reg != DFC && opP->reg != DFC
&& opP->reg != USP && opP->reg != USP
&& opP->reg != VBR) /* 68010's had only these */ && opP->reg != VBR) /* 68010's had only these */
|| ((current_architecture & m68040) == 0 || (cpu_of_arch(current_architecture) < m68040
&& opP->reg != SFC && opP->reg != SFC
&& opP->reg != DFC && opP->reg != DFC
&& opP->reg != USP && opP->reg != USP
@ -1444,7 +1441,7 @@ char *instring;
&& opP->reg != CAAR && opP->reg != CAAR
&& opP->reg != MSP && opP->reg != MSP
&& opP->reg != ISP) /* 680[23]0's have only these */ && opP->reg != ISP) /* 680[23]0's have only these */
|| ((current_architecture & m68040) /* 68040 has all but this */ || (cpu_of_arch(current_architecture) == m68040 /* 68040 has all but this */
&& opP->reg == CAAR)) { && opP->reg == CAAR)) {
losing++; losing++;
} /* doesn't cut it */ } /* doesn't cut it */
@ -1609,7 +1606,8 @@ char *instring;
losing = 0; losing = 0;
} }
/* now assemble it */
the_ins.args=opcode->m_operands; the_ins.args=opcode->m_operands;
the_ins.numargs=opcode->m_opnum; the_ins.numargs=opcode->m_opnum;
the_ins.numo=opcode->m_codenum; the_ins.numo=opcode->m_codenum;
@ -1778,9 +1776,7 @@ char *instring;
case APODX: case APODX:
case AMIND: case AMIND:
case APRDX: case APRDX:
if (max_arch_this_insn < m68020) { know(current_architecture & m68020up);
max_arch_this_insn = m68020;
} /* bump arch */
/* intentional fall-through */ /* intentional fall-through */
case AINDX: case AINDX:
nextword=0; nextword=0;
@ -1839,7 +1835,7 @@ char *instring;
/* It aint simple */ /* It aint simple */
nextword|=0x100; nextword|=0x100;
/* If the guy specified a width, we assume that /* If the guy specified a width, we assume that
it is wide enough. Maybe it isn't. Ifso, we lose it is wide enough. Maybe it isn't. If so, we lose
*/ */
switch(siz1) { switch(siz1) {
case 0: case 0:
@ -1934,7 +1930,7 @@ char *instring;
&& !subs(opP->con1) && !subs(opP->con1)
&& seg(opP->con1) == SEG_TEXT && seg(opP->con1) == SEG_TEXT
&& now_seg == SEG_TEXT && now_seg == SEG_TEXT
&& (current_architecture & m68000up) <= m68010 && cpu_of_arch(current_architecture) < m68020
&& !flagseen['S'] && !flagseen['S']
&& !strchr("~%&$?", s[0])) { && !strchr("~%&$?", s[0])) {
tmpreg=0x3A; /* 7.2 */ tmpreg=0x3A; /* 7.2 */
@ -2045,7 +2041,7 @@ char *instring;
break; break;
case 'L': case 'L':
long_branch: long_branch:
if(current_architecture <= m68010) /* 68000 or 010 */ if (cpu_of_arch(current_architecture) < m68020) /* 68000 or 010 */
as_warn("Can't use long branches on 68000/68010"); as_warn("Can't use long branches on 68000/68010");
the_ins.opcode[the_ins.numo-1]|=0xff; the_ins.opcode[the_ins.numo-1]|=0xff;
/* Offset the displacement to be relative to byte disp location */ /* Offset the displacement to be relative to byte disp location */
@ -2066,7 +2062,7 @@ char *instring;
where opnd is absolute (it needs where opnd is absolute (it needs
to use the 68000 hack since no to use the 68000 hack since no
conditional abs jumps). */ conditional abs jumps). */
if (((current_architecture <= m68010) || (0==adds(opP->con1))) if (((cpu_of_arch(current_architecture) < m68020) || (0==adds(opP->con1)))
&& (the_ins.opcode[0] >= 0x6200) && (the_ins.opcode[0] >= 0x6200)
&& (the_ins.opcode[0] <= 0x6f00)) { && (the_ins.opcode[0] <= 0x6f00)) {
add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF)); add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF));
@ -2667,6 +2663,18 @@ char *str;
char *to_beg_P; char *to_beg_P;
int shorts_this_frag; int shorts_this_frag;
if (current_architecture == 0) {
current_architecture = (m68020
#ifndef NO_68881
| m68881
#endif
#ifndef NO_68851
| m68851
#endif
);
} /* default current_architecture */
bzero((char *)(&the_ins),sizeof(the_ins)); /* JF for paranoia sake */ bzero((char *)(&the_ins),sizeof(the_ins)); /* JF for paranoia sake */
m68k_ip(str); m68k_ip(str);
er=the_ins.error; er=the_ins.error;
@ -2759,7 +2767,7 @@ char *str;
the_ins.reloc[m].pcrel, the_ins.reloc[m].pcrel,
NO_RELOC); NO_RELOC);
} }
know(the_ins.fragb[n].fadd); /* know(the_ins.fragb[n].fadd); */
(void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty), (void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty),
the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P); the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P);
} }
@ -3054,7 +3062,7 @@ register fragS *fragP;
ext=2; ext=2;
break; break;
case TAB(BRANCH,LONG): case TAB(BRANCH,LONG):
if (current_architecture <= m68010) { if (cpu_of_arch(current_architecture) < m68020) {
if (fragP->fr_opcode[0]==0x61) { if (fragP->fr_opcode[0]==0x61) {
fragP->fr_opcode[0]= 0x4E; fragP->fr_opcode[0]= 0x4E;
fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */ fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */
@ -3276,7 +3284,7 @@ segT segment;
&& S_GET_SEGMENT(fragP->fr_symbol) == segment) { && S_GET_SEGMENT(fragP->fr_symbol) == segment) {
fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
break; break;
} else if((fragP->fr_symbol == 0) || (current_architecture <= m68010)) { } else if((fragP->fr_symbol == 0) || (cpu_of_arch(current_architecture) < m68020)) {
/* On 68000, or for absolute value, switch to abs long */ /* On 68000, or for absolute value, switch to abs long */
/* FIXME, we should check abs val, pick short or long */ /* FIXME, we should check abs val, pick short or long */
if(fragP->fr_opcode[0]==0x61) { if(fragP->fr_opcode[0]==0x61) {
@ -3453,7 +3461,7 @@ symbolS *to_symbol;
{ {
long offset; long offset;
if (current_architecture <= m68010) { if (cpu_of_arch(current_architecture) < m68020) {
offset=to_addr-S_GET_VALUE(to_symbol); offset=to_addr-S_GET_VALUE(to_symbol);
md_number_to_chars(ptr ,(long)0x4EF9,2); md_number_to_chars(ptr ,(long)0x4EF9,2);
md_number_to_chars(ptr+2,(long)offset,4); md_number_to_chars(ptr+2,(long)offset,4);
@ -3752,14 +3760,16 @@ char ***vecP;
current_architecture |= m68040; current_architecture |= m68040;
#ifndef NO_68881 #ifndef NO_68881
} else if (!strcmp(*argP, "68881") } else if (!strcmp(*argP, "68881")) {
|| !strcmp(*argP, "68882")) { current_architecture |= m68881;
current_architecture |= m68040;
} else if (!strcmp(*argP, "68882")) {
current_architecture |= m68882;
#endif /* NO_68881 */ #endif /* NO_68881 */
#ifndef NO_68851 #ifndef NO_68851
} else if (!strcmp(*argP,"68851")) { } else if (!strcmp(*argP,"68851")) {
current_architecture |= m68040; current_architecture |= m68851;
#endif /* NO_68851 */ #endif /* NO_68851 */
} else { } else {