static bool
java_init (void)
{
  /* FIXME: Indirect dispatch isn't yet compatible with static class
     init optimization.  */
  if (flag_indirect_dispatch)
    always_initialize_class_p = true;

  if (!flag_indirect_dispatch)
    flag_indirect_classes = false;

  jcf_path_seal (v_flag);

  java_init_decl_processing ();

  using_eh_for_cleanups ();

  return true;
}
Exemple #2
0
int
main (int argc, char** argv)
{
  JCF jcf[1];
  int argi, opt;

  /* Unlock the stdio streams.  */
  unlock_std_streams ();

  gcc_init_libintl ();

  if (argc <= 1)
    {
      fprintf (stderr, _("jcf-dump: no classes specified\n"));
      usage ();
    }

  jcf_path_init ();

  /* We use getopt_long_only to allow single `-' long options.  For
     some of our options this is more natural.  */
  while ((opt = getopt_long_only (argc, argv, "o:I:vc", options, NULL)) != -1)
    {
      switch (opt)
	{
	case 0:
	  /* Already handled.  */
	  break;

        case 'o':
	  output_file = optarg;
	  break;

	case 'I':
	  jcf_path_include_arg (optarg);
	  break;

	case 'v':
	  verbose++;
	  break;

	case 'c':
	  flag_disassemble_methods = 1;
	  break;

	case OPT_classpath:
	  jcf_path_classpath_arg (optarg);
	  break;

	case OPT_bootclasspath:
	  jcf_path_bootclasspath_arg (optarg);
	  break;

	case OPT_extdirs:
	  jcf_path_extdirs_arg (optarg);
	  break;

	case OPT_HELP:
	  help ();
	  break;

	case OPT_VERSION:
	  version ();
	  break;

	case OPT_JAVAP:
	  flag_javap_compatible++;
	  flag_print_constant_pool = 0;
	  flag_print_attributes = 0;
	  break;

	default:
	  usage ();
	}
    }

  if (verbose && ! flag_javap_compatible)
    flag_print_constant_pool = 1;

  if (optind == argc)
    {
      fprintf (stderr, _("jcf-dump: no classes specified\n"));
      usage ();
    }

  jcf_path_seal (verbose);

  if (flag_print_main)
    {
      flag_print_fields = 0;
      flag_print_methods = 0;
      flag_print_constant_pool = 0;
      flag_print_attributes = 0;
      flag_print_class_info = 0;
    }

  if (output_file)
    {
      out = fopen (output_file, "w");
      if (! out)
	{
	  fprintf (stderr, _("Cannot open '%s' for output.\n"), output_file);
	  return FATAL_EXIT_CODE;
	}
    }
  else
    out = stdout;

  if (optind >= argc)
    {
      fprintf (out, "Reading .class from <standard input>.\n");
      open_class ("<stdio>", jcf, 0, NULL);
      process_class (jcf);
    }
  else
    {
      for (argi = optind; argi < argc; argi++)
	{
	  char *arg = argv[argi];
	  const char *class_filename = find_class (arg, strlen (arg), jcf, 0);
	  if (class_filename == NULL)
	    class_filename = find_classfile (arg, jcf, NULL);
	  if (class_filename == NULL)
	    {
	      perror ("Could not find class");
	      return FATAL_EXIT_CODE;
	    }
	  JCF_FILL (jcf, 4);
	  if (GET_u4 (jcf->read_ptr) == ZIPMAGIC)
	    {
	      long compressed_size, member_size;
	      int compression_method, filename_length, extra_length;
	      int general_purpose_bits;
	      const char *filename;
	      int total_length;
	      if (flag_print_class_info)
		fprintf (out, "Reading classes from archive %s.\n",
			 class_filename);
	      for (;;)
		{
		  int skip = 0;
		  jcf_filbuf_t save_filbuf = jcf->filbuf;
		  long magic = JCF_readu4_le (jcf);
		  if (magic == 0x02014b50 || magic == 0x06054b50)
		    break;  /* got to central directory */
		  if (magic != 0x04034b50) /* ZIPMAGIC (little-endian) */
		    {
		      fprintf (stderr, _("bad format of .zip/.jar archive\n"));
		      return FATAL_EXIT_CODE;
		    }
		  JCF_FILL (jcf, 26);
		  JCF_SKIP (jcf, 2);
		  general_purpose_bits = JCF_readu2_le (jcf);
		  compression_method = JCF_readu2_le (jcf);
		  JCF_SKIP (jcf, 8);
		  compressed_size = JCF_readu4_le (jcf);
		  member_size = JCF_readu4_le (jcf);
		  filename_length = JCF_readu2_le (jcf);
		  extra_length = JCF_readu2_le (jcf);
		  total_length = filename_length + extra_length
		    + compressed_size;
		  if (jcf->read_end - jcf->read_ptr < total_length)
		    jcf_trim_old_input (jcf);
		  JCF_FILL (jcf, total_length);
		  filename = (const char *) jcf->read_ptr;
		  JCF_SKIP (jcf, filename_length);
		  JCF_SKIP (jcf, extra_length);
		  if (filename_length > 0
		      && filename[filename_length-1] == '/')
		    {
		      if (flag_print_class_info)
			fprintf (out, "[Skipping directory %.*s]\n",
				 filename_length, filename);
		      skip = 1;
		    }
		  else if (compression_method != 0)
		    {
		      if (flag_print_class_info)
			fprintf (out, "[Skipping compressed file %.*s]\n",
				 filename_length, filename);
		      skip = 1;
		    }
		  else if (member_size < 4
			   || GET_u4 (jcf->read_ptr) != 0xcafebabe)
		    {
		      if (flag_print_class_info)
			fprintf (out, "[Skipping non-.class member %.*s]\n",
				 filename_length, filename);
		      skip = 1;
		    }
		  else
		    {
		      if (flag_print_class_info)
			fprintf (out, "Reading class member: %.*s.\n",
				 filename_length, filename);
		    }
		  if (skip)
		    {
		      JCF_SKIP (jcf, compressed_size);
		    }
		  else
		    {
		      unsigned char *save_end;
		      jcf->filbuf = jcf_unexpected_eof;
		      save_end = jcf->read_end;
		      jcf->read_end = jcf->read_ptr + compressed_size;
		      process_class (jcf);
		      jcf->filbuf = save_filbuf;
		      jcf->read_end = save_end;
		    }
		}
	    }
	  else
	    {
	      if (flag_print_class_info)
		fprintf (out, "Reading .class from %s.\n", class_filename);
	      process_class (jcf);
	    }
	  JCF_FINISH(jcf);
	}
    }

  return SUCCESS_EXIT_CODE;
}