Exemplo n.º 1
0
void
process_pragma(tree *expr)
{
  tree *lhs;
  tree *rhs;

  switch (expr->tag) {
  case node_binop:
    lhs = expr->value.binop.p0;
    rhs = expr->value.binop.p1;
    if ((expr->value.binop.op != '=') ||
        (lhs->tag != node_symbol)) {
      gp_error("unknown pragma");
    } else {
      if (strcasecmp(lhs->value.symbol, "processor") == 0) {
        if (rhs->tag != node_symbol) {
          gp_error("invalid processor name");        
        } else {
          if (state.processor_chosen == false) {
            select_processor(rhs->value.symbol);
          }        
        }
      } else {
        gp_error("unknown pragma \"%s\"", lhs->value.symbol);
      }
    }
    break;
  default:
    gp_error("unknown pragma");
  }
  
  return;
}
Exemplo n.º 2
0
void yyerror(char *message)
{
  gp_error("%s:%d:%s",
           state.src->name,
	   state.src->line_number,
	   message);
}
Exemplo n.º 3
0
void
strip_all(void)
{
  gp_section_type *section = state.object->sections;

  if (state.object->flags & F_EXEC) {
    while (section != NULL) {
      /* remove the line numbers, have too because the symbols will be
         removed */
      section->num_lineno = 0;
      section->line_numbers = NULL;
      section->line_numbers_tail = NULL;

      /* remove the relocations, they should already be removed */
      section->num_reloc = 0;
      section->relocations = NULL;
      section->relocations_tail = NULL;
    
      section = section->next;
    }  

    /* remove all symbols */
    state.object->num_symbols = 0;
    state.object->symbols = NULL;
    state.object->symbols_tail = NULL;

  } else {
    gp_error("can not strip all symbols because the object file is not executable");
  }
}
Exemplo n.º 4
0
void
select_processor(char *name)
{
  struct px *found = NULL;

  if (state.cmd_processor) {
    gp_warning("processor superseded by command line");
  } else {
    found = gp_find_processor(name);
    if (found) {
      if (state.processor == no_processor) {
        state.processor = found->tag;
        state.processor_info = found;
        /* FIXME: should the processor name be defined as a symbol? */
      } else if (state.processor != found->tag ) {
        gp_warning("redefining processor");
      }
    } else {
      gp_error("unknown processor \"%s\"", name);
    }
   
    /* load the instruction sets if necessary */
    if ((state.processor_chosen == false) && 
        (state.processor != no_processor)) {
      /* FIXME select the correct code generator */
      state.processor_chosen = true;
    }
  }
}
Exemplo n.º 5
0
void select_mode(enum lib_modes mode)
{
  if (state.mode == ar_null) { 
    state.mode = mode;
  } else {
    gp_error("multiple library operations selected");
  }
}
Exemplo n.º 6
0
void
codegen_init_asm()
{
  char buffer[BUFSIZ];

  /* open output filename */
  strncpy(state.asmfilename, state.basefilename, sizeof(state.asmfilename));
  strncat(state.asmfilename, ".asm", sizeof(state.asmfilename));
  state.output.f = fopen(state.asmfilename, "w");
  if (state.output.f == NULL) {
    perror(state.asmfilename);
    exit(1);
  }

  label_number = 0;
  max_temp_number = 0;
  codegen_working_bytes = 1;
  codegen_size = size_uint8;
  codegen_bytes = prim_size(codegen_size);

  gp_date_string(buffer, sizeof(buffer));

  fprintf(state.output.f, "; %s\n", state.asmfilename);
  fprintf(state.output.f, "; generated by %s on %s\n\n",
          GPAL_VERSION_STRING,
          buffer);

  fprintf(state.output.f, "#file \"%s\"\n\n", state.srcfilename);

  if (state.processor_chosen) {
    fprintf(state.output.f, "  processor %s\n", 
            state.processor_info->names[1]);
    fprintf(state.output.f, "  include \"%s.inc\"\n\n",
            state.processor_info->names[1]);
  } else {
    gp_error("processor not selected");
  } 

  if (state.section.code) {
    if (state.section.code_addr_valid) {
      fprintf(state.output.f, "%s code %#x\n", 
              state.section.code,
              state.section.code_addr);
    } else {
      fprintf(state.output.f, "%s code\n", state.section.code);
    }
  } else {
    if (state.section.code_addr_valid) {
      fprintf(state.output.f, ".code_%s code %#x\n", 
              FILE_NAME(state.module),
              state.section.code_addr);
    } else {
      fprintf(state.output.f, ".code_%s code\n", FILE_NAME(state.module));
    }
  }

  return;
}
Exemplo n.º 7
0
void
read_block(unsigned char *block, int block_number)
{
  int n;

  fseek(codefile, block_number * COD_BLOCK_SIZE, SEEK_SET);
  n = fread(block, 1, COD_BLOCK_SIZE, codefile);

  if (COD_BLOCK_SIZE != n) {
    gp_error("bad block number %d", block_number);
  }
}
Exemplo n.º 8
0
static void
write_expression(tree *statement)
{
  tree *lhs;
  tree *rhs;
  struct variable *var;
  char *lhs_name;

  fprintf(state.output.f, ";#CSRC %s %d\n", 
          state.srcfilename,
          statement->line_number);
  
  if ((statement->tag != node_binop) || 
      (statement->value.binop.op != '=')) {
    gp_error("invalid expression");
    return;
  }

  lhs = statement->value.binop.p0;
  rhs = statement->value.binop.p1;

  if (lhs->tag != node_symbol) {
    gp_error("invalid lvalue in assignment");
    return;
  }
  
  var = get_global(lhs->value.symbol);
  lhs_name = var->alias;

  temp_number = 0;
  gen_expr(rhs);

  if (var)
    gen_put_mem(lhs_name);

  if (temp_number > max_temp_number)
    max_temp_number = temp_number;

}
Exemplo n.º 9
0
struct variable *
get_global(char *name)
{
  struct symbol *sym;
  struct variable *var = NULL;

  sym = get_symbol(state.stGlobal, name);
  if (sym == NULL) {
    gp_error("undefined symbol \"%s\"", name);
  } else {
    var = get_symbol_annotation(sym);
  }

  return var;
}
Exemplo n.º 10
0
static void
write_declarations(void)
{
  entity *entity_list = NULL;
  tree *current = NULL;
  int first_time = 1;
  tree *list;  
  tree *symbol;

  entity_list = state.list;

  while (entity_list != NULL) {
    current = entity_list->node;
    if ((current->tag == node_decl) && 
        (current->value.decl.storage != EXTERN_STORAGE)) {
      if ((current->value.decl.type == CONST_TYPE) &&
          (current->value.decl.storage != 0)) {
        gp_error("constants can't be public or volatile");
      } 
      /* FIXME: only bytes are supported so far */
      assert(current->value.decl.size == BYTE_SIZE);
      if (first_time) {
        fprintf(state.output.f, "; declarations \n");
        fprintf(state.output.f, "  udata\n");
        first_time = 0;      
      }
      for (list = current->value.decl.expr; list; list = TAIL(list)) {
        symbol = HEAD(list);
        assert(symbol->tag == node_symbol);
        if (current->value.decl.type == VAR_TYPE) {
          fprintf(state.output.f, "%s res 1\n", symbol->value.symbol);
          if (current->value.decl.storage == PUBLIC_STORAGE)
            fprintf(state.output.f, "  global %s\n", symbol->value.symbol);
        }
        add_global(symbol->value.symbol, symbol->value.symbol, current);
      }
    }
    entity_list = entity_list->next;
  }

  if (!first_time)
    fprintf(state.output.f, "\n");

}
Exemplo n.º 11
0
void
add_global(char *name, char *alias, tree *object)
{
  struct symbol *sym;
  struct variable *var;

  sym = get_symbol(state.stGlobal, name);
  if (sym == NULL) {
    sym = add_symbol(state.stGlobal, name);
    var = malloc(sizeof(*var));
    annotate_symbol(sym, var);
    var->node = object;
    var->alias = strdup(alias);
    var->is_public = false;
    var->is_external = false;
  } else {
    gp_error("duplicate symbol \"%s\"", name);
  }
  
  return;
}
Exemplo n.º 12
0
static void
assemble(char *file_name, gp_boolean asm_source)
{
  char command[BUFSIZ];

  if ((gp_num_errors) || (state.compile_only == true))
    return;

  if (state.processor_chosen == false) {
    gp_error("processor not selected");
    exit(1);
  }

  strcpy(command, "gpasm -c ");

  if (gp_quiet) {
    strcat(command, "-q ");
  }  

  strcat(command, file_name);
  strcat(command, ".asm ");

  if (!gp_quiet) {
    printf("%s\n", command);
  }
  if (system(command)) {
    gp_num_errors++;
  } else if (state.delete_temps == true) {
    if (asm_source == false) {
      sprintf(command, "%s.asm", file_name);
      unlink(command);
    }
    sprintf(command, "%s.lst", file_name);
    unlink(command);
  }

  return;
}
Exemplo n.º 13
0
int main(int argc, char *argv[])
{
  extern int optind;
  int i = 0;
  int c;
  gp_boolean usage = false;
  gp_boolean update_archive = false;
  gp_boolean no_index = false;
  gp_archive_type *object = NULL;

  gp_init();

  /* symbols are case sensitive */
  definition_tbl = push_symbol_table(NULL, false);
  symbol_index = push_symbol_table(NULL, false);

  while ((c = GETOPT_FUNC) != EOF) {
    switch (c) {
    case '?':
    case 'h':
      usage = true;
      break;
    case 'c':
      select_mode(ar_create);
      break;
    case 'd':
      select_mode(ar_delete);
      break;
    case 'n':
      no_index = true;
      break;
    case 'q':
      gp_quiet = true;
      break;
    case 'r':
      select_mode(ar_replace);
      break;
    case 's':
      select_mode(ar_symbols);
      break;
    case 't':
      select_mode(ar_list);
      break;
    case 'v':
      fprintf(stderr, "%s\n", GPLIB_VERSION_STRING);
      exit(0);
      break;
    case 'x':
      select_mode(ar_extract);
      break;
    }
    if (usage)
      break;
  }

  if (optind < argc) {
    /* fetch the library name */
    state.filename = argv[optind++];
    /* some operations require object filenames or membernames */
    for ( ; optind < argc; optind++) {
      state.objectname[state.numobjects] = argv[optind];
      if (state.numobjects >= MAX_OBJ_NAMES) {
        gp_error("exceeded maximum number of object files");
        break;
      }
      state.numobjects++;
    }
  } else {
    usage = true;
  }

  /* User did not select an operation */
  if (state.mode == ar_null) {
    usage = true;
  }

  /* User did not provide object names */
  if ((state.mode != ar_list) && 
      (state.mode != ar_symbols) && 
      (state.numobjects == 0)) {
    usage = true;
  }

  if (usage) {
    show_usage();
  }

  /* if we are not creating a new archive, we have to read an existing one */
  if (state.mode != ar_create) {
    if (gp_identify_coff_file(state.filename) != archive_file) {
      gp_error("\"%s\" is not a valid archive file", state.filename);
      exit(1);
    } else {
      state.archive = gp_archive_read(state.filename);
    }
  }
    
  /* process the option */
  i = 0;
  switch (state.mode) {
  case ar_create: 
  case ar_replace:
    while (i < state.numobjects) {
      if (gp_identify_coff_file(state.objectname[i]) != object_file) {
        gp_error("\"%s\" is not a valid object file", state.objectname[i]);
        break;
      } else {
        state.archive = gp_archive_add_member(state.archive, 
                                              state.objectname[i],
                                              object_name(state.objectname[i]));
      }
      i++;
    }
    update_archive = true;
    break;

  case ar_delete: 
    while (i < state.numobjects) {
      if (has_path(state.objectname[i])) {
        gp_error("invalid object name \"%s\"", state.objectname[i]);
        break;
      }
      object = gp_archive_find_member(state.archive, state.objectname[i]);
      if (object == NULL) {
        gp_error("object \"%s\" not found", state.objectname[i]);
        break;
      } else {
        state.archive = gp_archive_delete_member(state.archive, 
                                                 state.objectname[i]);
      }
      i++;
    }
    update_archive = true;
    break;

  case ar_extract:
    while (i < state.numobjects) {
      if (has_path(state.objectname[i])) {
        gp_error("invalid object name \"%s\"", state.objectname[i]);
        break;
      }
      object = gp_archive_find_member(state.archive, state.objectname[i]);
      if (object == NULL) {
        gp_error("object \"%s\" not found", state.objectname[i]);
        break;
      } else {
        if (gp_archive_extract_member(state.archive, state.objectname[i])) {
          gp_error("can't write file \"%s\"", state.objectname[i]);
          break;
        }
      }
      i++;
    } 
    break;

  case ar_list:
    gp_archive_list_members(state.archive);
    break;

  case ar_symbols:
    if (gp_archive_have_index(state.archive) == 0) {
      gp_error("this archive has no symbol index");
    } else {
      gp_archive_read_index(symbol_index, state.archive);
      gp_archive_print_table(symbol_index);
    }
    break;

  case ar_null:
  default:
    assert(0);
  }

  /* If the archive is being modified remove the old symbol index */
  if (update_archive) {
    state.archive = gp_archive_remove_index(state.archive);
  }

  /* check for duplicate symbols */
  gp_archive_make_index(state.archive, definition_tbl);

  /* add the symbol index to the archive */      
  if (update_archive && (!no_index)) {
    state.archive = gp_archive_add_index(definition_tbl, state.archive);
  }

  /* write the new or modified archive */
  if (update_archive && (gp_num_errors == 0)) {
    if (gp_archive_write(state.archive, state.filename))
      gp_error("can't write the new archive file");
  }

  if (gp_num_errors > 0)
    return EXIT_FAILURE;
  else
    return EXIT_SUCCESS;

}
Exemplo n.º 14
0
int main(int argc, char *argv[])
{
  extern int optind;
  int c;
  int usage = 0;

  gp_init();

  /* initalize */
  verbose = false;
  state.strip_debug = false;
  state.preserve_dates = false;
  state.strip_all = false;
  state.strip_unneeded = false;
  state.discard_all = false;
  state.output_file = NULL;
  state.symbol_keep = push_symbol_table(NULL, false);
  state.symbol_remove = push_symbol_table(NULL, false);
  state.section_remove = push_symbol_table(NULL, false);

  while ((c = GETOPT_FUNC) != EOF) {
    switch (c) {
    case '?':
    case 'h':
      usage = 1;
      break;
    case 'g':
      state.strip_debug = true;
      break;
    case 'k':
      add_name(state.symbol_keep, optarg);
      break;
    case 'n':
      add_name(state.symbol_remove, optarg);
      break;
    case 'o':
      state.output_file = optarg;
      break;
    case 'p':
      state.preserve_dates = true;
      break;
    case 'r':
      add_name(state.section_remove, optarg);
      break;
    case 's':
      state.strip_all = true;
      break;
    case 'u':
      state.strip_unneeded = true;
      break;
    case 'x':
      state.discard_all = true;
      break;
    case 'V':
      verbose = true;
      break;
    case 'v':
      fprintf(stderr, "%s\n", GPSTRIP_VERSION_STRING);
      exit(0);
    }
    if (usage)
      break;
  }

  if ((optind == argc) || (usage)) {
    show_usage();
  }

  for ( ; optind < argc; optind++) {
    state.input_file = argv[optind];

    if (gp_identify_coff_file(state.input_file) != object_file_v2 && 
        gp_identify_coff_file(state.input_file) != object_file) {
      gp_error("\"%s\" is not a valid object file", state.input_file);
      exit(1);
    }

    state.object = gp_read_coff(state.input_file);

    if (state.object) {
      remove_sections();
      remove_symbols();
    
      if (state.strip_all) {
        strip_all();
      }

      if (state.strip_debug) {
        if (state.strip_all) {
          gp_message("strip debug ignored");
        } else {
          strip_debug();
        }
      }

      if (state.strip_unneeded) {
        if (state.strip_all) {
          gp_message("strip unneeded ignored");
        } else {
          strip_unneeded();
        }
      }

      if (state.discard_all) {
        if (state.strip_all) {
          gp_message("discard all ignored");
        } else {
          discard_all();
        }
      }

      if (state.output_file) {
        state.object->filename = state.output_file;
      }

      if (!state.preserve_dates) {
        /* FIXME: need to update the output file dates */
        state.object->time = (long)time(NULL);
      }
    
      if (gp_num_errors == 0) {
        /* no errors have occured so write the file */
        if (gp_write_coff(state.object, 0))
          gp_error("system error while writing object file");
      } else if (state.output_file) {
        /* a new file is being written, but errors have occurred, delete
           the file if it exists */
        unlink(state.output_file);
      }

      /* FIXME: free state.output_file */
    }
  }


  if (gp_num_errors)
    return EXIT_FAILURE;
  else
    return EXIT_SUCCESS;
}
Exemplo n.º 15
0
void
process_args( int argc, char *argv[])
{
  extern char *optarg;
  extern int optind;
  int c;
  int usage = 0;

  while ((c = getopt_long(argc, argv, GET_OPTIONS, longopts, 0)) != EOF) {
    switch (c) {
    case '?':
    case 'h':
      usage = 1;
      break;
    case 'a':
      state.archive = true;
      break;    
    case 'c':
      state.no_link = true;
      break;    
    case 'd':
      gp_debug_disable = 0;
      break;
    case 'I':
      add_path(optarg);
      break;    
    case 'k':
      state.options = optarg;
      break;
    case 'l':
      gp_dump_processor_list();
      exit(0);
      break;
    case 'o':
      state.outfilename = strdup(optarg);
      break;
    case 'p':
      select_processor(optarg);
      state.cmd_processor = true;
      break;
    case 'q':
      gp_quiet = 1;
      break;
    case 'S':
      state.compile_only = true;
      break;    
    case 't':
      state.delete_temps = false;
      break;    
    case 'v':
      fprintf(stderr, "%s\n", GPAL_VERSION_STRING);
      exit(0);
      
    }
    if (usage)
      break;
  }
  
  if (optind < argc) {
    for ( ; optind < argc; optind++) {
      state.file_name[state.num_files] = argv[optind];
      if (state.num_files >= MAX_FILE_NAMES) {
        gp_error("exceeded maximum number of source files");
        break;
      }
      state.num_files++;
    }
  } else {
    usage = 1;
  }

  if (usage) {
    show_usage();
  }

}