crt_name = module->str_table + crt_sym->st_name;
strong_count = 0;
- weak_count = 0;
+ weak_count = (ELF32_ST_BIND(crt_sym->st_info) == STB_WEAK);
for_each_module(crt_module)
{
if (crt_sym->st_shndx == SHN_UNDEF)
{
// We have an undefined symbol
+ //
+ // We use the weak_count to differentiate
+ // between Syslinux-derivative-specific
+ // functions. For example, unload_pxe() is
+ // only provided by PXELINUX, so we mark it as
+ // __weak and replace it with a reference to
+ // undefined_symbol() on SYSLINUX, EXTLINUX,
+ // and ISOLINUX. See perform_relocations().
if (strong_count == 0 && weak_count == 0)
{
DBG_PRINT("Symbol %s is undefined\n", crt_name);
#include <stdio.h>
#include <elf.h>
#include <dprintf.h>
+#include <core.h>
#include <linux/list.h>
#include <sys/module.h>
return 0;
}
+void undefined_symbol(void)
+{
+ printf("Error: An undefined symbol was referenced\n");
+ kaboom();
+}
static int perform_relocation(struct elf_module *module, Elf32_Rel *rel) {
Elf32_Word *dest = module_get_absolute(rel->r_offset, module);
&sym_module);
if (sym_def == NULL) {
- // This should never happen
DBG_PRINT("Cannot perform relocation for symbol %s\n",
module->str_table + sym_ref->st_name);
- return -1;
+ if (ELF32_ST_BIND(sym_ref->st_info) != STB_WEAK)
+ return -1;
+
+ // This must be a derivative-specific
+ // function. We're OK as long as we never
+ // execute the function.
+ sym_def = global_find_symbol("undefined_symbol", &sym_module);
}
// Compute the absolute symbol virtual address