diff options
author | Michael Tiemann <tiemann@cygnus> | 1991-11-24 17:24:52 +0000 |
---|---|---|
committer | Michael Tiemann <tiemann@cygnus> | 1991-11-24 17:24:52 +0000 |
commit | 865a2edf64c0f7544581dc4cb7a3b82f542009d3 (patch) | |
tree | 68e1f6ff9d6b0dc1d936134fa2afe3b55a32d99d /gas | |
parent | 5bcc23e3b28d230939b099ff5751222e3e1a6379 (diff) | |
download | gdb-865a2edf64c0f7544581dc4cb7a3b82f542009d3.zip gdb-865a2edf64c0f7544581dc4cb7a3b82f542009d3.tar.gz gdb-865a2edf64c0f7544581dc4cb7a3b82f542009d3.tar.bz2 |
Ensure we null-terminate the string we copy at the start of
m68k_reg_parse.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/config/tc-m68k.c | 226 |
1 files changed, 118 insertions, 108 deletions
diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 3b9f7dc..546e538 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -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 { |