diff options
Diffstat (limited to 'nuttx/binfmt')
-rw-r--r-- | nuttx/binfmt/libelf/libelf.h | 6 | ||||
-rw-r--r-- | nuttx/binfmt/libelf/libelf_bind.c | 30 | ||||
-rw-r--r-- | nuttx/binfmt/libelf/libelf_symbols.c | 22 |
3 files changed, 51 insertions, 7 deletions
diff --git a/nuttx/binfmt/libelf/libelf.h b/nuttx/binfmt/libelf/libelf.h index e1382ee2d..4304e64f2 100644 --- a/nuttx/binfmt/libelf/libelf.h +++ b/nuttx/binfmt/libelf/libelf.h @@ -174,6 +174,12 @@ int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index, * 0 (OK) is returned on success and a negated errno is returned on * failure. * + * EINVAL - There is something inconsistent in the symbol table (should only + * happen if the file is corrupted) + * ENOSYS - Symbol lies in common + * ESRCH - Symbol has no name + * ENOENT - Symbol undefined and not provided via a symbol table + * ****************************************************************************/ int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym, diff --git a/nuttx/binfmt/libelf/libelf_bind.c b/nuttx/binfmt/libelf/libelf_bind.c index 608f65ef7..58ceb148f 100644 --- a/nuttx/binfmt/libelf/libelf_bind.c +++ b/nuttx/binfmt/libelf/libelf_bind.c @@ -136,6 +136,7 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx, FAR Elf32_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info]; Elf32_Rel rel; Elf32_Sym sym; + FAR Elf32_Sym *psym; uintptr_t addr; int symidx; int ret; @@ -148,6 +149,8 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx, for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++) { + psym = &sym; + /* Read the relocation entry into memory */ ret = elf_readrel(loadinfo, relsec, i, &rel); @@ -179,9 +182,28 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx, ret = elf_symvalue(loadinfo, &sym, exports, nexports); if (ret < 0) { - bdbg("Section %d reloc %d: Failed to get value of symbol[%d]: %d\n", - relidx, i, symidx, ret); - return ret; + /* The special error -ESRCH is returned only in one condition: The + * symbol has no name. + * + * There are a few relocations for a few architectures that do + * no depend upon a named symbol. We don't know if that is the + * case here, but we will use a NULL symbol pointer to indicate + * that case to up_relocate(). That function can then do what + * is best. + */ + + if (ret == -ESRCH) + { + bdbg("Section %d reloc %d: Undefined symbol[%d] has no name: %d\n", + relidx, i, symidx, ret); + psym = NULL; + } + else + { + bdbg("Section %d reloc %d: Failed to get value of symbol[%d]: %d\n", + relidx, i, symidx, ret); + return ret; + } } /* Calculate the relocation address. */ @@ -197,7 +219,7 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx, /* Now perform the architecture-specific relocation */ - ret = up_relocate(&rel, &sym, addr); + ret = up_relocate(&rel, psym, addr); if (ret < 0) { bdbg("ERROR: Section %d reloc %d: Relocation failed: %d\n", ret); diff --git a/nuttx/binfmt/libelf/libelf_symbols.c b/nuttx/binfmt/libelf/libelf_symbols.c index bd7942a67..40831d2ec 100644 --- a/nuttx/binfmt/libelf/libelf_symbols.c +++ b/nuttx/binfmt/libelf/libelf_symbols.c @@ -1,7 +1,7 @@ /**************************************************************************** * binfmt/libelf/libelf_symbols.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -76,6 +76,10 @@ * 0 (OK) is returned on success and a negated errno is returned on * failure. * + * EINVAL - There is something inconsistent in the symbol table (should only + * happen if the file is corrupted). + * ESRCH - Symbol has no name + * ****************************************************************************/ static int elf_symname(FAR struct elf_loadinfo_s *loadinfo, @@ -94,7 +98,7 @@ static int elf_symname(FAR struct elf_loadinfo_s *loadinfo, if (sym->st_name == 0) { bdbg("Symbol has no name\n"); - return -ENOENT; + return -ESRCH; } offset = loadinfo->shdr[loadinfo->strtabidx].sh_offset + sym->st_name; @@ -253,6 +257,12 @@ int elf_readsym(FAR struct elf_loadinfo_s *loadinfo, int index, * 0 (OK) is returned on success and a negated errno is returned on * failure. * + * EINVAL - There is something inconsistent in the symbol table (should only + * happen if the file is corrupted). + * ENOSYS - Symbol lies in common + * ESRCH - Symbol has no name + * ENOENT - Symbol undefined and not provided via a symbol table + * ****************************************************************************/ int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym, @@ -269,7 +279,7 @@ int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym, /* NuttX ELF modules should be compiled with -fno-common. */ bdbg("SHN_COMMON: Re-compile with -fno-common\n"); - return -EINVAL; + return -ENOSYS; } case SHN_ABS: @@ -287,6 +297,12 @@ int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym, ret = elf_symname(loadinfo, sym); if (ret < 0) { + /* There are a few relocations for a few architectures that do + * no depend upon a named symbol. We don't know if that is the + * case here, but return and special error to the caller to + * indicate the nameless symbol. + */ + bdbg("SHN_UNDEF: Failed to get symbol name: %d\n", ret); return ret; } |