Logo Search packages:      
Sourcecode: linux86 version File versions  Download package

as.c

/* as.c - assembler */

/*
  usage: as source [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] [-guw]
  in any order (but no repeated file options)
*/

#include "syshead.h"
#include "const.h"
#include "type.h"
#include "byteord.h"
#include "macro.h"
#undef EXTERN
#define EXTERN
#include "file.h"
#include "flag.h"
#include "globvar.h"
#include "version.h"

PUBLIC char hexdigit[] = "0123456789ABCDEF";    /* XXX - ld uses lower case */

PRIVATE struct block_s hid_blockstak[MAXBLOCK]; /* block stack */
PRIVATE struct lc_s hid_lctab[NLOC];      /* location counter table */
PRIVATE struct if_s hid_ifstak[MAXBLOCK]; /* if stack */
PRIVATE struct schain_s hid_mcpar[MACPSIZ];     /* MACRO params */
PRIVATE struct macro_s hid_macstak[MAXBLOCK];   /* macro stack */
PRIVATE struct sym_s *hid_spt[SPTSIZ];    /* hash table */

PRIVATE char * binfilename = 0;
PRIVATE char * objfilename = 0;

FORWARD void initp1 P((void));
FORWARD int my_creat P((char *name, char *message));
FORWARD void process_args P((int argc, char **argv));
FORWARD void summary P((fd_t fd));
FORWARD void summ_number P((unsigned num));
FORWARD void usage P((void));

PUBLIC int main(argc, argv)
int argc;
char **argv;
{
    init_heap();
    initp1();
    initp1p2();
    inst_keywords();
    initbin();
    initobj();
    initsource();
    typeconv_init(INT_BIG_ENDIAN, LONG_BIG_ENDIAN);
    as_warn.global = TRUE;          /* constant */
    as_warn.semaphore = -1;
    last_pass=1;
    process_args(argc, argv);
    initscan();
    line_zero();

    assemble();               /* doesn't return, maybe use setjmp */

    /* NOTREACHED */
    return 0;
}

PUBLIC void as_abort(message)
char *message;
{
    write(STDOUT, "as: ", 4);
    write(STDOUT, message, strlen(message));
    write(STDOUT, "\n", 1);
    exit(1);
}

PUBLIC void finishup()
{
    bintrailer();
    objtrailer();
    if (list.global ||symgen)
      gensym();         /* output to lstfil and/or symfil */
    if (list.global ||toterr != 0 || totwarn != 0)
      summary(lstfil);
    if (lstfil != STDOUT && (toterr != 0 || totwarn != 0))
      summary(STDOUT);
    statistics();

    /* If an output binary is in error remove it */
    close(binfil); binfil=0;
    close(objfil); objfil=0;
    if (toterr != 0) 
    {
       if(binfilename) unlink(binfilename);
       if(objfilename) unlink(objfilename);
    }

    exit(toterr != 0 ? 1 : 0);      /* should close output files and check */
}

/* initialise constant nonzero values */

PRIVATE void initp1()
{
#ifdef I80386
    idefsize = defsize = 2;   /* I think this is probably safer (RDB) */
#endif
#if 0
    idefsize = defsize = sizeof (char *) > 2 ? 4 : 2;
#endif
    lctabtop = lctab + NLOC;
    lstfil = STDOUT;
    mapnum = 15;        /* default map number for symbol table */
    spt_top = (spt = hid_spt) + SPTSIZ;
}

/* initialise nonzero values which start same each pass */

PUBLIC void initp1p2()
{
    register struct lc_s *lcp;

    dirty_pass = 0;
    ifflag = TRUE;
    pedata = UNDBIT;          /* program entry point not defined */
    blockstak = hid_blockstak + MAXBLOCK;
    ifstak = hid_ifstak + MAXIF;
    macstak = hid_macstak + MAXMAC;
    macptop = (macpar = hid_mcpar) + MACPSIZ;
    lctabtop = (lcptr = lctab = hid_lctab) + NLOC;
    for (lcp = lctab; lcp < lctabtop; ++lcp)
    {
      lcp->data = lcdata = RELBIT;  /* lc relocatable until 1st ORG */
      lcp->lc = lc = 0;
    }
}

PUBLIC void line_zero()
{
   if( textseg >= 0 )
      ptext();
}

PRIVATE int my_creat(name, message)
char *name;
char *message;
{
    int fd;

#ifdef O_BINARY
    if ((fd = open(name, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, CREAT_PERMS)) < 0 || fd > 255)
#else
    if ((fd = creat(name, CREAT_PERMS)) < 0 || fd > 255)
#endif
      as_abort(message);
    return fd;
}

PRIVATE void process_args(argc, argv)
int argc;
char **argv;
{
    char *arg;
    bool_t isnextarg;
    char *nextarg = 0;
    int opened_file = 0;
    int flag_state;

#ifdef I80386
    setcpu(0xF);
#endif
    textseg = -1;

    if (argc <= 1)
      usage();
    do
    {
      arg = *++argv;
      if (arg[0] == '-' && arg[1] != '\0')
      {
          flag_state = 1;
          if (arg[2] == '-' && arg[3] == 0 )
             flag_state = 0;
          else
          if (arg[2] != 0)
            usage();    /* no multiple options */
          isnextarg = FALSE;
          if (argc > 2)
          {
            nextarg = argv[1];
            if (nextarg[0] != 0 && nextarg[0] != '-')
                isnextarg = TRUE;
          }
          switch (arg[1])
          {
          case 'v':
             outfd = STDOUT;
             writes("as86 version: ");
             writesn(VERSION);
             exit(1);
#ifdef I80386
          case '0': case '1': case '2':
            idefsize = defsize = 0x2;
            setcpu(arg[1]-'0');
            break;
          case '3':
            idefsize = defsize = 0x4;
            setcpu(0xF);
            break;
          case 'a':
            asld_compatible = flag_state;
            break;
#endif
          case 'b':
            if (!isnextarg || binfil != 0)
                usage();
            binfil = my_creat(binfilename=nextarg, "error creating binary file");
            binaryg = TRUE;
            --argc;
            ++argv;
            break;
          case 'g':
            globals_only_in_obj = flag_state;
            break;
#ifdef I80386
          case 'j':
            jumps_long = flag_state;
            break;
          case 'O':
            if( flag_state ) last_pass = 2;
            else             last_pass = 1;
            break;
#endif
          case 'l':
            list.global = TRUE;
            goto get_any_list_file;
          case 'm':
            maclist.global = TRUE;
      get_any_list_file:
            if (isnextarg)
            {
                if (lstfil != STDOUT)
                  usage();
                lstfil = my_creat(nextarg, "error creating list file");
                --argc;
                ++argv;
            }
            break;
          case 'n':
            if (!isnextarg)
                usage();
            truefilename = nextarg;
            --argc;
            ++argv;
            break;
          case 'o':
            if (!isnextarg || objfil != 0)
                usage();
            objectg = TRUE;
            objfil = my_creat(objfilename=nextarg, "error creating object file");
            --argc;
            ++argv;
            break;
          case 's':
            if (!isnextarg || symfil != 0)
                usage();
            symgen = TRUE;
            symfil = my_creat(nextarg, "error creating symbol file");
            --argc;
            ++argv;
            break;
          case 't':
            if (!isnextarg || binfil != 0)
                usage();
            textseg = atoi(nextarg); if(textseg>0) textseg+=BSSLOC;
            --argc;
            ++argv;
            break;
          case 'u':
            if( flag_state ) inidata = IMPBIT | SEGM;
            else             inidata = 0;
            break;
          case 'w':
            if( flag_state ) as_warn.semaphore = -1;
            else             as_warn.semaphore = 0;
            break;
          default:
            usage();    /* bad option */
          }
      }
      else if (infil != 0)
          usage();            /* no multiple sources */
      else
      {
          if (strlen(arg) > FILNAMLEN)
            as_abort("source file name too long");
          infiln = infil0 = 1;
          infil = open_input(strcpy(filnamptr, arg));
          opened_file = 1;
      }
    }
    while (--argc != 1);
    if( !opened_file )
    {
       infiln = infil0 = 1;
       infil = open_input(strcpy(filnamptr, "-"));
    }
#ifdef I80386
    origcpuid = cpuid;
#endif
    inidata = (~binaryg & inidata) | (RELBIT | UNDBIT);
}                       /* IMPBIT from inidata unless binaryg */

PRIVATE void summary(fd)
int fd;
{
    outfd = fd;
    writenl();
    summ_number(toterr);
    writesn(" errors");
    summ_number(totwarn);
    writesn(" warnings");
}

PRIVATE void summ_number(num)
unsigned num;
{
    /* format number like line numbers */
    char buf[16];
    *build_number(num, LINUM_LEN, buf) = 0;
    writes(buf);
}

PRIVATE void usage()
{
    as_abort(
#ifdef I80386
"usage: as [-03agjuwO] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src");
#else
    "usage: as [-guw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src");
#endif
}

Generated by  Doxygen 1.6.0   Back to index