Permalink
Browse files

exe,elf: fix main symbol resolution

The dynamic symbol table search for main yielded the address of the PLT
stub on clang, which in turn is not used by the entry point. This was
causing Criterion to fork-bomb the user when running test workers, as
they would spawn a new runner every time.

Users are advised to use a check mechanism, like setting an environment
variable, and abort immediately when seeing this environment variable
in the runner's main function.
  • Loading branch information...
Snaipe committed Oct 29, 2018
1 parent 4bac60b commit 926bd4ce968592dbbba97ec1bb9aeca3edf29b0d
Showing with 1 addition and 27 deletions.
  1. +1 −27 src/exe-elf.c
@@ -193,32 +193,6 @@ static ElfSym *dynsym_lookup(bxfi_exe_lib lib, const char *name)

extern int main(void);

static void *get_main_addr(bxfi_exe_ctx ctx)
{
/* It just so happens that `main` can exist in the symbol hash table of
our executable if it is a dynamic symbol, and gives the address of
its PLT stub.
Effectively, we don't need to traverse the link map list, but
this is the exception rather than the norm. */
struct link_map *lm = ctx->r_map;

/* First, do a fast lookup in the dynamic symbol hash table to get
the PLT address if we have a dynamic symbol */
ElfSym *sym = dynsym_lookup(lm, "main");

uintptr_t base = (uintptr_t)lm->l_addr;

if (sym) {
if (sym->st_value >= base)
return (void *) sym->st_value;
else
return (void *) (sym->st_value + base);
}

/* Otherwise, we fallback to whatever the linker says */
return nonstd (void *) &main;
}

extern void *bxfi_trampoline;
extern void *bxfi_trampoline_addr;
extern void *bxfi_trampoline_end;
@@ -229,7 +203,7 @@ extern void *bxfi_trampoline_end;

int bxfi_exe_patch_main(bxfi_exe_fn *new_main)
{
void *addr = get_main_addr(init_exe_ctx());
void *addr = nonstd (void *) &main;

if (!addr)
return -1;

0 comments on commit 926bd4c

Please sign in to comment.