Skip to content

Commit

Permalink
Merge pull request #119 from ethereum/loader
Browse files Browse the repository at this point in the history
Generalize loader searching algorithm
  • Loading branch information
chfast committed Aug 31, 2018
2 parents 4955ebf + eadcd23 commit 297ce06
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [6.0.0-dev] - unreleased

- Improved: [[#119](https://github.com/ethereum/evmc/pull/119)]
EVMC loader symbol searching has been generalized.

## [5.2.0] - 2018-08-28

- Feature: [[#81](https://github.com/ethereum/evmc/pull/81)]
Expand Down
15 changes: 8 additions & 7 deletions include/evmc/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,16 @@ enum evmc_loader_error_code
* "libexample-interpreter.so",
* - the "lib" prefix and file extension are stripped from the name:
* "example-interpreter"
* - all "-" are replaced with "_" to construct _full name_:
* - all "-" are replaced with "_" to construct _base name_:
* "example_interpreter",
* - the _full name_ is split by "_" char and the last item is taken to form the _short name_:
* "interpreter",
* - the name "evmc_create_" + _full name_ is checked in the library:
* - the function name "evmc_create_" + _base name_ is searched in the library:
* "evmc_create_example_interpreter",
* - then, the name "evmc_create_" + _short name_ is checked in the library:
* "evmc_create_interpreter".
* - lastly, the name "evmc_create" is checked in the library
* - if function not found, the _base name_ is shorten by skipping the first word separated by "_":
* "interpreter",
* - then, the function of the shorter name "evmc_create_" + _base name_ is searched in the library:
* "evmc_create_interpreter",
* - the name shortening continues until a function is found or the name cannot be shorten more,
* - lastly, when no function found, the function name "evmc_create" is searched in the library.
*
* If the create function is found in the library, the pointer to the function is returned.
* Otherwise, the ::EVMC_LOADER_SYMBOL_NOT_FOUND error code is signaled and NULL is returned.
Expand Down
30 changes: 14 additions & 16 deletions lib/loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
// Create name buffer with the prefix.
const char prefix[] = "evmc_create_";
const size_t prefix_length = strlen(prefix);
char name[sizeof(prefix) + PATH_MAX_LENGTH];
strcpy_s(name, sizeof(name), prefix);
char prefixed_name[sizeof(prefix) + PATH_MAX_LENGTH];
strcpy_s(prefixed_name, sizeof(prefixed_name), prefix);

// Find filename in the path.
const char* sep_pos = strrchr(filename, '/');
Expand All @@ -87,30 +87,28 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
if (strncmp(name_pos, lib_prefix, lib_prefix_length) == 0)
name_pos += lib_prefix_length;

strcpy_s(name + prefix_length, PATH_MAX_LENGTH, name_pos);
char* base_name = prefixed_name + prefix_length;
strcpy_s(base_name, PATH_MAX_LENGTH, name_pos);

// Trim the file extension.
char* ext_pos = strrchr(name, '.');
char* ext_pos = strrchr(prefixed_name, '.');
if (ext_pos)
*ext_pos = 0;

// Replace all "-" with "_".
char* dash_pos = name;
char* dash_pos = base_name;
while ((dash_pos = strchr(dash_pos, '-')) != NULL)
*dash_pos++ = '_';

// Search for the "full name" based function name.
create_fn = DLL_GET_CREATE_FN(handle, name);
if (!create_fn)
// Search for the built function name.
while ((create_fn = DLL_GET_CREATE_FN(handle, prefixed_name)) == NULL)
{
// Try the "short name" based function name.
const char* short_name_pos = strrchr(name, '_');
if (short_name_pos)
{
short_name_pos += 1;
memmove(name + prefix_length, short_name_pos, strlen(short_name_pos) + 1);
create_fn = DLL_GET_CREATE_FN(handle, name);
}
// Shorten the base name by skipping the `word_` segment.
const char* shorter_name_pos = strchr(base_name, '_');
if (!shorter_name_pos)
break;

memmove(base_name, shorter_name_pos + 1, strlen(shorter_name_pos) + 1);
}

if (!create_fn)
Expand Down

0 comments on commit 297ce06

Please sign in to comment.