Skip to content

export-file-local-symbol A,B: selective export of file-local symbols #6339

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

Closed
wants to merge 2 commits into from
Closed
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
3 changes: 2 additions & 1 deletion doc/architectural/static-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ We should now also write a harness for `private_function`. However,
since that function is marked `static`, it is not possible for functions
in external files to call it. We can write and link a harness by
stripping the `static` attribute from `private_function` using goto-cc's
`--export-file-local-symbols` flag.
`--export-file-local-symbols` or `--export-file-local-symbol private_function`
flag.

\code{.sh}
> goto-cc -c -o --export-file-local-symbols library_with_static.o library.c
Expand Down
3 changes: 3 additions & 0 deletions regression/goto-cc-file-local/chain.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ fi
export_flag=""
if is_in old-flag "$ALL_ARGS"; then
export_flag="--export-function-local-symbols"
elif is_in "export-[a-zA-Z0-9_,]*-only" "$ALL_ARGS"; then
names=${ALL_ARGS#*export-}
export_flag="--export-file-local-symbol ${names%-only*}"
else
export_flag="--export-file-local-symbols"
fi
Expand Down
14 changes: 14 additions & 0 deletions regression/goto-cc-file-local/selected-symbols/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
static int foo(int x)
{
return x + 1;
}

static int bar(int x)
{
return x + 2;
}

static int baz(int x)
{
return x + 2;
}
10 changes: 10 additions & 0 deletions regression/goto-cc-file-local/selected-symbols/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
main.c
export-foo,bar-only show-symbol-table
^Symbol\.\.\.\.\.\.: __CPROVER_file_local_main_c_foo$
^Symbol\.\.\.\.\.\.: __CPROVER_file_local_main_c_bar$
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
^Symbol\.\.\.\.\.\.: __CPROVER_file_local_main_c_baz$
2 changes: 1 addition & 1 deletion src/ansi-c/ansi_c_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ bool ansi_c_languaget::parse(
bool ansi_c_languaget::typecheck(
symbol_tablet &symbol_table,
const std::string &module,
const bool keep_file_local)
const std::string &keep_file_local)
{
symbol_tablet new_symbol_table;

Expand Down
4 changes: 2 additions & 2 deletions src/ansi-c/ansi_c_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class ansi_c_languaget:public languaget
bool typecheck(
symbol_tablet &symbol_table,
const std::string &module,
const bool keep_file_local) override;
const std::string &keep_file_local) override;

bool can_keep_file_local() override
{
Expand All @@ -64,7 +64,7 @@ class ansi_c_languaget:public languaget
bool
typecheck(symbol_tablet &symbol_table, const std::string &module) override
{
return typecheck(symbol_table, module, true);
return typecheck(symbol_table, module, ".*");
}

void show_parse(std::ostream &out) override;
Expand Down
2 changes: 1 addition & 1 deletion src/cpp/cpp_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ bool cpp_languaget::typecheck(
cpp_parse_tree, new_symbol_table, module, get_message_handler()))
return true;

remove_internal_symbols(new_symbol_table, get_message_handler(), false);
remove_internal_symbols(new_symbol_table, get_message_handler(), "");

return linking(symbol_table, new_symbol_table, get_message_handler());
}
Expand Down
44 changes: 38 additions & 6 deletions src/goto-cc/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Date: June 2006
#include <util/get_base_name.h>
#include <util/prefix.h>
#include <util/run.h>
#include <util/string_utils.h>
#include <util/symbol_table_builder.h>
#include <util/tempdir.h>
#include <util/tempfile.h>
Expand Down Expand Up @@ -353,10 +354,13 @@ bool compilet::link(optionalt<symbol_tablet> &&symbol_table)
convert_symbols(goto_model);
}

if(keep_file_local)
if(!keep_file_local.empty())
{
function_name_manglert<file_name_manglert> mangler(
log.get_message_handler(), goto_model, file_local_mangle_suffix);
log.get_message_handler(),
goto_model,
file_local_mangle_suffix,
keep_file_local);
mangler.mangle();
}

Expand Down Expand Up @@ -424,10 +428,13 @@ optionalt<symbol_tablet> compilet::compile()
else
cfn = output_file_object;

if(keep_file_local)
if(!keep_file_local.empty())
{
function_name_manglert<file_name_manglert> mangler(
log.get_message_handler(), file_goto_model, file_local_mangle_suffix);
log.get_message_handler(),
file_goto_model,
file_local_mangle_suffix,
keep_file_local);
mangler.mangle();
}

Expand Down Expand Up @@ -645,15 +652,40 @@ optionalt<symbol_tablet> compilet::parse_source(const std::string &file_name)
return std::move(file_symbol_table);
}

/// Combine the elements of \p values to a regular expression denoting
/// alternatives. Each element of \p values may in turn be a sequence of
/// comma-separated values, which are also expanded to contribute to the overall
/// collection of alternatives.
static std::string csv_to_pattern(const std::list<std::string> &values)
{
std::string result;

for(const auto &csv : values)
{
for(const auto &name : split_string(csv, ','))
{
if(!result.empty())
result += '|';
result += name;
}
}

return result;
}

/// constructor
compilet::compilet(cmdlinet &_cmdline, message_handlert &mh, bool Werror)
: log(mh),
cmdline(_cmdline),
warning_is_fatal(Werror),
keep_file_local(
// function-local is the old name and is still in use, but is misleading
cmdline.isset("export-function-local-symbols") ||
cmdline.isset("export-file-local-symbols")),
(cmdline.isset("export-function-local-symbols") ||
cmdline.isset("export-file-local-symbols"))
? ".*"
: (cmdline.isset("export-file-local-symbol")
? csv_to_pattern(cmdline.get_values("export-file-local-symbol"))
: "")),
file_local_mangle_suffix(
cmdline.isset("mangle-suffix") ? cmdline.get_value("mangle-suffix") : "")
{
Expand Down
2 changes: 1 addition & 1 deletion src/goto-cc/compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class compilet
bool warning_is_fatal;

/// \brief Whether to keep implementations of file-local symbols
const bool keep_file_local;
const std::string keep_file_local;

/// \brief String to include in all mangled names
const std::string file_local_mangle_suffix;
Expand Down
1 change: 1 addition & 0 deletions src/goto-cc/gcc_cmdline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const char *goto_cc_options_with_separated_argument[]=
"--print-rejected-preprocessed-source",
"--mangle-suffix",
"--object-bits",
"--export-file-local-symbol",
nullptr
};

Expand Down
6 changes: 6 additions & 0 deletions src/goto-cc/goto_cc_mode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ void goto_cc_modet::help()
" --native-compiler cmd command to invoke as preprocessor/compiler\n"
" --native-linker cmd command to invoke as linker\n"
" --native-assembler cmd command to invoke as assembler (goto-as only)\n"
" --export-file-local-symbols\n"
" name-mangle and export file-local symbols\n"
" --export-file-local-symbol A,B\n"
" export file-local symbols as above, but\n"
" restrict this operation to symbols A and B\n"
" --mangle-suffix suffix append suffix to exported file-local symbols\n"
" --print-rejected-preprocessed-source file\n"
" copy failing (preprocessed) source to file\n"
" --object-bits number of bits used for object addresses\n"
Expand Down
4 changes: 3 additions & 1 deletion src/goto-cc/ms_cl_cmdline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const char *non_ms_cl_options[]=
"--validate-goto-model",
"--export-file-local-symbols",
"--mangle-suffix",
"--export-file-local-symbol",
nullptr
};
// clang-format on
Expand All @@ -62,7 +63,8 @@ bool ms_cl_cmdlinet::parse(const std::vector<std::string> &arguments)

if(
arguments[i] == "--verbosity" || arguments[i] == "--function" ||
arguments[i] == "--mangle-suffix")
arguments[i] == "--mangle-suffix" ||
arguments[i] == "--export-file-local-symbol")
{
if(i < arguments.size() - 1)
{
Expand Down
16 changes: 13 additions & 3 deletions src/goto-programs/name_mangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,20 @@ class function_name_manglert
{
public:
/// \param mh: handler to construct a log from
/// \param gm: mangle all names in gm's symbol table and goto program
/// \param gm: mangle names in gm's symbol table and goto program
/// \param extra_info: a string to be included in each mangled name
/// \param needs_mangling: a regular expression describing names that need to
/// be mangled.
function_name_manglert(
message_handlert &mh,
goto_modelt &gm,
const std::string &extra_info)
: log(mh), model(gm), mangle_fun(), extra_info(extra_info)
const std::string &extra_info,
const std::string &needs_mangling)
: log(mh),
model(gm),
mangle_fun(),
extra_info(extra_info),
needs_mangling(needs_mangling)
{
}

Expand Down Expand Up @@ -65,6 +72,8 @@ class function_name_manglert
continue;
if(!sym.is_file_local)
continue;
if(!std::regex_match(id2string(sym.name), needs_mangling))
continue;

const irep_idt mangled = mangle_fun(sym, extra_info);
symbolt new_sym;
Expand Down Expand Up @@ -136,6 +145,7 @@ class function_name_manglert
goto_modelt &model;
MangleFun mangle_fun;
const std::string &extra_info;
const std::regex needs_mangling;
};

/// \brief Mangle identifiers by including their filename
Expand Down
2 changes: 1 addition & 1 deletion src/langapi/language.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class languaget:public messaget
virtual bool typecheck(
symbol_tablet &symbol_table,
const std::string &module,
const bool keep_file_local)
const std::string &keep_file_local)
{
INVARIANT(
false,
Expand Down
6 changes: 3 additions & 3 deletions src/langapi/language_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ bool language_filest::parse()

bool language_filest::typecheck(
symbol_tablet &symbol_table,
const bool keep_file_local)
const std::string &keep_file_local)
{
// typecheck interfaces

Expand Down Expand Up @@ -204,7 +204,7 @@ bool language_filest::interfaces(
bool language_filest::typecheck_module(
symbol_tablet &symbol_table,
const std::string &module,
const bool keep_file_local)
const std::string &keep_file_local)
{
// check module map

Expand All @@ -222,7 +222,7 @@ bool language_filest::typecheck_module(
bool language_filest::typecheck_module(
symbol_tablet &symbol_table,
language_modulet &module,
const bool keep_file_local)
const std::string &keep_file_local)
{
// already typechecked?

Expand Down
9 changes: 5 additions & 4 deletions src/langapi/language_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ class language_filest:public messaget

bool generate_support_functions(symbol_tablet &symbol_table);

bool
typecheck(symbol_tablet &symbol_table, const bool keep_file_local = false);
bool typecheck(
symbol_tablet &symbol_table,
const std::string &keep_file_local = "");

bool final(symbol_table_baset &symbol_table);

Expand Down Expand Up @@ -144,12 +145,12 @@ class language_filest:public messaget
bool typecheck_module(
symbol_tablet &symbol_table,
language_modulet &module,
const bool keep_file_local);
const std::string &keep_file_local);

bool typecheck_module(
symbol_tablet &symbol_table,
const std::string &module,
const bool keep_file_local);
const std::string &keep_file_local);
};

#endif // CPROVER_UTIL_LANGUAGE_FILE_H
10 changes: 7 additions & 3 deletions src/linking/remove_internal_symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Author: Daniel Kroening

#include "static_lifetime_init.h"

#include <regex>

static void get_symbols(
const namespacet &ns,
const symbolt &in_symbol,
Expand Down Expand Up @@ -99,12 +101,12 @@ static void get_symbols(
/// on "extern inline"
/// \param symbol_table: symbol table to clean up
/// \param mh: log handler
/// \param keep_file_local: keep file-local functions with bodies even if we
/// \param keep_file_local: regular expression over symbols to keep even if we
/// would otherwise remove them
void remove_internal_symbols(
symbol_tablet &symbol_table,
message_handlert &mh,
const bool keep_file_local)
const std::string &keep_file_local)
{
namespacet ns(symbol_table);
find_symbols_sett exported;
Expand Down Expand Up @@ -176,7 +178,9 @@ void remove_internal_symbols(
{
get_symbols(ns, symbol, exported);
}
else if(has_body && is_file_local && keep_file_local)
else if(
has_body && is_file_local && !keep_file_local.empty() &&
std::regex_match(id2string(symbol.name), std::regex(keep_file_local)))
{
get_symbols(ns, symbol, exported);
}
Expand Down
4 changes: 3 additions & 1 deletion src/linking/remove_internal_symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ Author: Daniel Kroening
#ifndef CPROVER_LINKING_REMOVE_INTERNAL_SYMBOLS_H
#define CPROVER_LINKING_REMOVE_INTERNAL_SYMBOLS_H

#include <string>

class message_handlert;

void remove_internal_symbols(
class symbol_tablet &symbol_table,
message_handlert &,
const bool);
const std::string &);

#endif // CPROVER_LINKING_REMOVE_INTERNAL_SYMBOLS_H
4 changes: 2 additions & 2 deletions src/statement-list/statement_list_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ bool statement_list_languaget::generate_support_functions(
bool statement_list_languaget::typecheck(
symbol_tablet &symbol_table,
const std::string &module,
const bool keep_file_local)
const std::string &keep_file_local)
{
symbol_tablet new_symbol_table;

Expand Down Expand Up @@ -85,7 +85,7 @@ bool statement_list_languaget::typecheck(
symbol_tablet &symbol_table,
const std::string &module)
{
return typecheck(symbol_table, module, true);
return typecheck(symbol_table, module, ".*");
}

bool statement_list_languaget::from_expr(
Expand Down
Loading