Ensure we null-terminate the string we copy at the start of
m68k_reg_parse.
This commit is contained in:
parent
5bcc23e3b2
commit
865a2edf64
1 changed files with 118 additions and 108 deletions
|
@ -314,8 +314,11 @@ struct m68k_it {
|
|||
} 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 enum m68k_architecture max_arch_this_insn;
|
||||
|
||||
/* Macros for adding things to the m68k_it struct */
|
||||
|
||||
|
@ -412,14 +415,7 @@ static void s_proc();
|
|||
|
||||
#endif /* __STDC__ */
|
||||
|
||||
static enum m68k_architecture current_architecture = m68020
|
||||
#ifndef NO_68881
|
||||
| m68881
|
||||
#endif
|
||||
#ifndef NO_68851
|
||||
| m68851
|
||||
#endif
|
||||
;
|
||||
static enum m68k_architecture current_architecture = 0;
|
||||
|
||||
/* BCC68000 is for patching in an extra jmp instruction for long offsets
|
||||
on the 68000. The 68000 doesn't support long branches with branchs */
|
||||
|
@ -558,9 +554,16 @@ register char **ccp;
|
|||
} /* need prefix */
|
||||
#endif
|
||||
|
||||
for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN && *q != 0; ++p, ++q) {
|
||||
*p = mklower(*q);
|
||||
} /* downcase */
|
||||
for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q)
|
||||
{
|
||||
if (*q == 0)
|
||||
{
|
||||
*p = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
*p = mklower(*q);
|
||||
} /* downcase */
|
||||
|
||||
switch(c[0]) {
|
||||
case 'a':
|
||||
|
@ -835,38 +838,37 @@ register struct m68k_op *opP;
|
|||
|
||||
if(i!=FAIL && (*str=='/' || *str=='-')) {
|
||||
opP->mode=REGLST;
|
||||
return get_regs(i,str,opP);
|
||||
return(get_regs(i,str,opP));
|
||||
}
|
||||
if ((stmp=strchr(str,'@')) != '\0') {
|
||||
opP->con1=add_exp(str,stmp-1);
|
||||
if(stmp==strend) {
|
||||
opP->mode=AINDX;
|
||||
return OK;
|
||||
return(OK);
|
||||
}
|
||||
|
||||
if ((current_architecture & m68020up) == 0) {
|
||||
return(FAIL);
|
||||
} /* if target is not a '20 or better */
|
||||
|
||||
stmp++;
|
||||
if(*stmp++!='(' || *strend--!=')') {
|
||||
opP->error="Malformed operand";
|
||||
return FAIL;
|
||||
return(FAIL);
|
||||
}
|
||||
i=try_index(&stmp,opP);
|
||||
opP->con2=add_exp(stmp,strend);
|
||||
|
||||
if (i == FAIL) {
|
||||
opP->mode=AMIND;
|
||||
if (max_arch_this_insn < m68020) {
|
||||
max_arch_this_insn = m68020;
|
||||
} /* bump arch */
|
||||
} else {
|
||||
opP->mode=APODX;
|
||||
if (max_arch_this_insn < m68020) {
|
||||
max_arch_this_insn = m68020;
|
||||
} /* bump arch */
|
||||
}
|
||||
return OK;
|
||||
return(OK);
|
||||
} /* if there's an '@' */
|
||||
opP->mode=ABSL;
|
||||
opP->con1=add_exp(str,strend);
|
||||
return OK;
|
||||
opP->mode = ABSL;
|
||||
opP->con1 = add_exp(str,strend);
|
||||
return(OK);
|
||||
} /* not a register, not exactly a register, or no '@' */
|
||||
|
||||
opP->reg=i;
|
||||
|
@ -957,89 +959,84 @@ register struct m68k_op *opP;
|
|||
}
|
||||
/* We've now got offset) offset,reg) or reg) */
|
||||
|
||||
if(*str=='\0') {
|
||||
if (*str == '\0') {
|
||||
/* Th-the-thats all folks */
|
||||
if(opP->reg==FAIL) opP->mode=AINDX; /* Other form of indirect */
|
||||
else if(opP->ireg==FAIL) opP->mode=AOFF;
|
||||
else opP->mode=AINDX;
|
||||
return OK;
|
||||
if (opP->reg == FAIL) opP->mode = AINDX; /* Other form of indirect */
|
||||
else if(opP->ireg == FAIL) opP->mode = AOFF;
|
||||
else opP->mode = AINDX;
|
||||
return(OK);
|
||||
}
|
||||
/* Next thing had better be another @ */
|
||||
if(*str!='@' || str[1]!='(') {
|
||||
opP->error="junk after indirect";
|
||||
return FAIL;
|
||||
opP->error = "junk after indirect";
|
||||
return(FAIL);
|
||||
}
|
||||
|
||||
if ((current_architecture & m68020up) == 0) {
|
||||
return(FAIL);
|
||||
} /* if target is not a '20 or better */
|
||||
|
||||
str+=2;
|
||||
if(opP->ireg!=FAIL) {
|
||||
opP->mode=APRDX;
|
||||
|
||||
if (max_arch_this_insn < m68020) {
|
||||
max_arch_this_insn = m68020;
|
||||
} /* bump arch */
|
||||
|
||||
i=try_index(&str,opP);
|
||||
if(i!=FAIL) {
|
||||
opP->error="Two index registers! not allowed!";
|
||||
return FAIL;
|
||||
|
||||
if(opP->ireg != FAIL) {
|
||||
opP->mode = APRDX;
|
||||
|
||||
i = try_index(&str, opP);
|
||||
if (i != FAIL) {
|
||||
opP->error = "Two index registers! not allowed!";
|
||||
return(FAIL);
|
||||
}
|
||||
} else
|
||||
i=try_index(&str,opP);
|
||||
} else {
|
||||
i = try_index(&str, opP);
|
||||
}
|
||||
|
||||
if (i == FAIL) {
|
||||
char *beg_str;
|
||||
|
||||
beg_str=str;
|
||||
for(i=1;i;) {
|
||||
beg_str = str;
|
||||
|
||||
for (i = 1; i; ) {
|
||||
switch(*str++) {
|
||||
case '\0':
|
||||
opP->error="Missing )";
|
||||
return FAIL;
|
||||
return(FAIL);
|
||||
case ',': i=0; break;
|
||||
case '(': i++; break;
|
||||
case ')': --i; break;
|
||||
}
|
||||
}
|
||||
|
||||
opP->con2=add_exp(beg_str,str-2);
|
||||
if(str[-1]==',') {
|
||||
if(opP->ireg!=FAIL) {
|
||||
opP->error="Can't have two index regs";
|
||||
return FAIL;
|
||||
|
||||
if (str[-1] == ',') {
|
||||
if (opP->ireg != FAIL) {
|
||||
opP->error = "Can't have two index regs";
|
||||
return(FAIL);
|
||||
}
|
||||
i=try_index(&str,opP);
|
||||
if(i==FAIL) {
|
||||
opP->error="malformed index reg";
|
||||
return FAIL;
|
||||
|
||||
i = try_index(&str, opP);
|
||||
|
||||
if (i == FAIL) {
|
||||
opP->error = "malformed index reg";
|
||||
return(FAIL);
|
||||
}
|
||||
opP->mode=APODX;
|
||||
if (max_arch_this_insn < m68020) {
|
||||
max_arch_this_insn = m68020;
|
||||
} /* bump arch */
|
||||
} else if(opP->ireg!=FAIL) {
|
||||
opP->mode=APRDX;
|
||||
|
||||
if (max_arch_this_insn < m68020) {
|
||||
max_arch_this_insn = m68020;
|
||||
} /* bump arch */
|
||||
|
||||
opP->mode = APODX;
|
||||
} else if (opP->ireg != FAIL) {
|
||||
opP->mode = APRDX;
|
||||
} else {
|
||||
opP->mode=AMIND;
|
||||
|
||||
if (max_arch_this_insn < m68020) {
|
||||
max_arch_this_insn = m68020;
|
||||
} /* bump arch */
|
||||
opP->mode = AMIND;
|
||||
}
|
||||
} else {
|
||||
opP->mode=APODX;
|
||||
if (max_arch_this_insn < m68020) {
|
||||
max_arch_this_insn = m68020;
|
||||
} /* bump arch */
|
||||
opP->mode = APODX;
|
||||
}
|
||||
|
||||
if(*str!='\0') {
|
||||
opP->error="Junk after indirect";
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
return(OK);
|
||||
} /* m68k_ip_op() */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -1206,8 +1203,6 @@ char *instring;
|
|||
LITTLENUM_TYPE words[6];
|
||||
LITTLENUM_TYPE *wordp;
|
||||
|
||||
max_arch_this_insn = m68000;
|
||||
|
||||
if (*instring == ' ')
|
||||
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 */
|
||||
/* 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 */
|
||||
for (losing = 0; ; ) {
|
||||
/* if we didn't get the right number of ops, or either
|
||||
the modes of our args or this op line itself are out
|
||||
of order... */
|
||||
/* if we didn't get the right number of ops,
|
||||
or we have no common model with this pattern
|
||||
then reject this pattern. */
|
||||
|
||||
if ((opsfound != opcode->m_opnum)
|
||||
|| ((max_arch_this_insn > current_architecture)
|
||||
|| (opcode->m_arch > current_architecture))) {
|
||||
if (opsfound != opcode->m_opnum
|
||||
|| ((opcode->m_arch & current_architecture) == 0)) {
|
||||
|
||||
++losing;
|
||||
|
||||
} else {
|
||||
|
@ -1291,8 +1286,10 @@ char *instring;
|
|||
it belongs to. I hope this makes sense. */
|
||||
switch(*s) {
|
||||
case '!':
|
||||
if(opP->mode==MSCR || opP->mode==IMMED ||
|
||||
opP->mode==DREG || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST)
|
||||
if (opP->mode == MSCR || opP->mode == IMMED
|
||||
|| opP->mode == DREG || opP->mode == AREG
|
||||
|| opP->mode == AINC || opP->mode == ADEC
|
||||
|| opP->mode == REGLST)
|
||||
losing++;
|
||||
break;
|
||||
|
||||
|
@ -1429,13 +1426,13 @@ char *instring;
|
|||
if (opP->mode != MSCR
|
||||
|| opP->reg < USP
|
||||
|| opP->reg > URP
|
||||
|| (current_architecture & m68000up) < m68010 /* before 68010 had none */
|
||||
|| ((current_architecture & m68020up) == 0
|
||||
|| cpu_of_arch(current_architecture) < m68010 /* before 68010 had none */
|
||||
|| (cpu_of_arch(current_architecture) < m68020
|
||||
&& opP->reg != SFC
|
||||
&& opP->reg != DFC
|
||||
&& opP->reg != USP
|
||||
&& opP->reg != VBR) /* 68010's had only these */
|
||||
|| ((current_architecture & m68040) == 0
|
||||
|| (cpu_of_arch(current_architecture) < m68040
|
||||
&& opP->reg != SFC
|
||||
&& opP->reg != DFC
|
||||
&& opP->reg != USP
|
||||
|
@ -1444,7 +1441,7 @@ char *instring;
|
|||
&& opP->reg != CAAR
|
||||
&& opP->reg != MSP
|
||||
&& 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)) {
|
||||
losing++;
|
||||
} /* doesn't cut it */
|
||||
|
@ -1609,7 +1606,8 @@ char *instring;
|
|||
losing = 0;
|
||||
}
|
||||
|
||||
|
||||
/* now assemble it */
|
||||
|
||||
the_ins.args=opcode->m_operands;
|
||||
the_ins.numargs=opcode->m_opnum;
|
||||
the_ins.numo=opcode->m_codenum;
|
||||
|
@ -1778,9 +1776,7 @@ char *instring;
|
|||
case APODX:
|
||||
case AMIND:
|
||||
case APRDX:
|
||||
if (max_arch_this_insn < m68020) {
|
||||
max_arch_this_insn = m68020;
|
||||
} /* bump arch */
|
||||
know(current_architecture & m68020up);
|
||||
/* intentional fall-through */
|
||||
case AINDX:
|
||||
nextword=0;
|
||||
|
@ -1839,7 +1835,7 @@ char *instring;
|
|||
/* It aint simple */
|
||||
nextword|=0x100;
|
||||
/* 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) {
|
||||
case 0:
|
||||
|
@ -1934,7 +1930,7 @@ char *instring;
|
|||
&& !subs(opP->con1)
|
||||
&& seg(opP->con1) == SEG_TEXT
|
||||
&& now_seg == SEG_TEXT
|
||||
&& (current_architecture & m68000up) <= m68010
|
||||
&& cpu_of_arch(current_architecture) < m68020
|
||||
&& !flagseen['S']
|
||||
&& !strchr("~%&$?", s[0])) {
|
||||
tmpreg=0x3A; /* 7.2 */
|
||||
|
@ -2045,7 +2041,7 @@ char *instring;
|
|||
break;
|
||||
case 'L':
|
||||
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");
|
||||
the_ins.opcode[the_ins.numo-1]|=0xff;
|
||||
/* Offset the displacement to be relative to byte disp location */
|
||||
|
@ -2066,7 +2062,7 @@ char *instring;
|
|||
where opnd is absolute (it needs
|
||||
to use the 68000 hack since no
|
||||
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] <= 0x6f00)) {
|
||||
add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF));
|
||||
|
@ -2667,6 +2663,18 @@ char *str;
|
|||
char *to_beg_P;
|
||||
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 */
|
||||
m68k_ip(str);
|
||||
er=the_ins.error;
|
||||
|
@ -2759,7 +2767,7 @@ char *str;
|
|||
the_ins.reloc[m].pcrel,
|
||||
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),
|
||||
the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P);
|
||||
}
|
||||
|
@ -3054,7 +3062,7 @@ register fragS *fragP;
|
|||
ext=2;
|
||||
break;
|
||||
case TAB(BRANCH,LONG):
|
||||
if (current_architecture <= m68010) {
|
||||
if (cpu_of_arch(current_architecture) < m68020) {
|
||||
if (fragP->fr_opcode[0]==0x61) {
|
||||
fragP->fr_opcode[0]= 0x4E;
|
||||
fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */
|
||||
|
@ -3276,7 +3284,7 @@ segT segment;
|
|||
&& S_GET_SEGMENT(fragP->fr_symbol) == segment) {
|
||||
fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
|
||||
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 */
|
||||
/* FIXME, we should check abs val, pick short or long */
|
||||
if(fragP->fr_opcode[0]==0x61) {
|
||||
|
@ -3453,7 +3461,7 @@ symbolS *to_symbol;
|
|||
{
|
||||
long offset;
|
||||
|
||||
if (current_architecture <= m68010) {
|
||||
if (cpu_of_arch(current_architecture) < m68020) {
|
||||
offset=to_addr-S_GET_VALUE(to_symbol);
|
||||
md_number_to_chars(ptr ,(long)0x4EF9,2);
|
||||
md_number_to_chars(ptr+2,(long)offset,4);
|
||||
|
@ -3752,14 +3760,16 @@ char ***vecP;
|
|||
current_architecture |= m68040;
|
||||
|
||||
#ifndef NO_68881
|
||||
} else if (!strcmp(*argP, "68881")
|
||||
|| !strcmp(*argP, "68882")) {
|
||||
current_architecture |= m68040;
|
||||
} else if (!strcmp(*argP, "68881")) {
|
||||
current_architecture |= m68881;
|
||||
|
||||
} else if (!strcmp(*argP, "68882")) {
|
||||
current_architecture |= m68882;
|
||||
|
||||
#endif /* NO_68881 */
|
||||
#ifndef NO_68851
|
||||
} else if (!strcmp(*argP,"68851")) {
|
||||
current_architecture |= m68040;
|
||||
current_architecture |= m68851;
|
||||
|
||||
#endif /* NO_68851 */
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue