Skip to content

TG-1743 Force-load ArrayList, HashSet, HashMap and StringReader #1633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions src/java_bytecode/ci_lazy_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,33 @@

#include <goto-programs/resolve_concrete_function_call.h>


/// Constructor for lazy-method loading
/// \param symbol_table: the symbol table to use
/// \param main_class: identifier of the entry point / main class
/// \param main_jar_classes: specify main class of jar if \p main_class is empty
/// \param lazy_methods_extra_entry_points: entry point functions to use
/// \param java_class_loader: the Java class loader to use
/// \param extra_needed_classes: list of class identifiers which are considered
/// to be required and therefore their methods should not be removed via
/// `lazy-methods`. Example of use: `ArrayList` as general implementation for
/// `List` interface.
/// \param pointer_type_selector: selector to handle correct pointer types
/// \param message_handler: the message handler to use for output
ci_lazy_methodst::ci_lazy_methodst(
const symbol_tablet &symbol_table,
const irep_idt &main_class,
const std::vector<irep_idt> &main_jar_classes,
const std::vector<irep_idt> &lazy_methods_extra_entry_points,
java_class_loadert &java_class_loader,
const std::vector<irep_idt> &extra_needed_classes,
const select_pointer_typet &pointer_type_selector,
message_handlert &message_handler):
messaget(message_handler),
message_handlert &message_handler)
: messaget(message_handler),
main_class(main_class),
main_jar_classes(main_jar_classes),
lazy_methods_extra_entry_points(lazy_methods_extra_entry_points),
java_class_loader(java_class_loader),
extra_needed_classes(extra_needed_classes),
pointer_type_selector(pointer_type_selector)
{
// build the class hierarchy
Expand Down Expand Up @@ -279,6 +292,10 @@ void ci_lazy_methodst::initialize_needed_classes(
lazy_methods.add_needed_class("java::java.lang.String");
lazy_methods.add_needed_class("java::java.lang.Class");
lazy_methods.add_needed_class("java::java.lang.Object");

// As in class_loader, ensure these classes stay available
for(const auto &id : extra_needed_classes)
lazy_methods.add_needed_class("java::" + id2string(id));
}

/// Build up list of methods for types for a pointer and any types it
Expand Down
2 changes: 2 additions & 0 deletions src/java_bytecode/ci_lazy_methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class ci_lazy_methodst:public messaget
const std::vector<irep_idt> &main_jar_classes,
const std::vector<irep_idt> &lazy_methods_extra_entry_points,
java_class_loadert &java_class_loader,
const std::vector<irep_idt> &extra_needed_classes,
const select_pointer_typet &pointer_type_selector,
message_handlert &message_handler);

Expand Down Expand Up @@ -111,6 +112,7 @@ class ci_lazy_methodst:public messaget
std::vector<irep_idt> main_jar_classes;
std::vector<irep_idt> lazy_methods_extra_entry_points;
java_class_loadert &java_class_loader;
const std::vector<irep_idt> &extra_needed_classes;
const select_pointer_typet &pointer_type_selector;
};

Expand Down
8 changes: 8 additions & 0 deletions src/java_bytecode/java_bytecode_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ void java_bytecode_languaget::get_language_options(const cmdlinet &cmd)
else
lazy_methods_mode=LAZY_METHODS_MODE_EAGER;

if(cmd.isset("java-load-class"))
{
for(const auto &c : cmd.get_values("java-load-class"))
java_load_classes.push_back(c);
}

const std::list<std::string> &extra_entry_points=
cmd.get_values("lazy-methods-extra-entry-point");
lazy_methods_extra_entry_points.insert(
Expand Down Expand Up @@ -128,6 +134,7 @@ bool java_bytecode_languaget::parse(
PRECONDITION(language_options_initialized);
java_class_loader.set_message_handler(get_message_handler());
java_class_loader.set_java_cp_include_files(java_cp_include_files);
java_class_loader.add_load_classes(java_load_classes);

// look at extension
if(has_suffix(path, ".class"))
Expand Down Expand Up @@ -323,6 +330,7 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
main_jar_classes,
lazy_methods_extra_entry_points,
java_class_loader,
java_load_classes,
get_pointer_type_selector(),
get_message_handler());

Expand Down
22 changes: 13 additions & 9 deletions src/java_bytecode/java_bytecode_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ Author: Daniel Kroening, [email protected]

#include <java_bytecode/select_pointer_type.h>

#define JAVA_BYTECODE_LANGUAGE_OPTIONS /*NOLINT*/ \
"(java-assume-inputs-non-null)" \
"(java-throw-runtime-exceptions)" \
"(java-max-input-array-length):" \
"(java-max-input-tree-depth):" \
"(java-max-vla-length):" \
"(java-cp-include-files):" \
"(lazy-methods)" \
"(lazy-methods-extra-entry-point):"
#define JAVA_BYTECODE_LANGUAGE_OPTIONS /*NOLINT*/ \
"(java-assume-inputs-non-null)" \
"(java-throw-runtime-exceptions)" \
"(java-max-input-array-length):" \
"(java-max-input-tree-depth):" \
"(java-max-vla-length):" \
"(java-cp-include-files):" \
"(lazy-methods)" \
"(lazy-methods-extra-entry-point):" \
"(java-load-class):"

#define JAVA_BYTECODE_LANGUAGE_OPTIONS_HELP /*NOLINT*/ \
" --java-assume-inputs-non-null never initialize reference-typed parameter to the\n" \
Expand Down Expand Up @@ -177,6 +178,9 @@ class java_bytecode_languaget:public languaget
java_string_library_preprocesst string_preprocess;
std::string java_cp_include_files;

// list of classes to force load even without reference from the entry point
std::vector<irep_idt> java_load_classes;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this fields seems duplicated here and in java_class_loader.h, if they are different I suggest finding better names


private:
const std::unique_ptr<const select_pointer_typet> pointer_type_selector;
};
Expand Down
13 changes: 13 additions & 0 deletions src/java_bytecode/java_class_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ java_bytecode_parse_treet &java_class_loadert::operator()(
queue.push("java.lang.Throwable");
queue.push(class_name);

// Require user provided classes to be loaded even without explicit reference
for(const auto &id : java_load_classes)
queue.push(id);

java_class_loader_limitt class_loader_limit(
get_message_handler(), java_cp_include_files);

Expand Down Expand Up @@ -278,3 +282,12 @@ jar_filet &java_class_loadert::jar_pool(
else
return it->second;
}

/// Adds the list of classes to the load queue, forcing them to be loaded even
/// without explicit reference
/// \param classes: list of class identifiers
void java_class_loadert::add_load_classes(const std::vector<irep_idt> &classes)
{
for(const auto &id : classes)
java_load_classes.push_back(id);
}
2 changes: 2 additions & 0 deletions src/java_bytecode/java_class_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class java_class_loadert:public messaget
java_bytecode_parse_treet &operator()(const irep_idt &);

void set_java_cp_include_files(std::string &);
void add_load_classes(const std::vector<irep_idt> &);

static std::string file_to_class_name(const std::string &);
static std::string class_name_to_file(const irep_idt &);
Expand Down Expand Up @@ -94,6 +95,7 @@ class java_class_loadert:public messaget
std::string java_cp_include_files;
private:
std::map<std::string, jar_filet> m_archives;
std::vector<irep_idt> java_load_classes;
};

#endif // CPROVER_JAVA_BYTECODE_JAVA_CLASS_LOADER_H