mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 23:03:27 +08:00
binfmt/libelf/ and libs/libc/modlib: Add symbol buffer table to reduce filesystem access.
This commit is contained in:
@@ -53,5 +53,12 @@ config ELF_RELOCATION_BUFFERCOUNT
|
|||||||
int "ELF Relocation Table Buffer Count"
|
int "ELF Relocation Table Buffer Count"
|
||||||
default 256
|
default 256
|
||||||
---help---
|
---help---
|
||||||
This is an cache buffer that is used to store elf relocation table to
|
This is an relocation buffer that is used to store elf relocation table to
|
||||||
|
reduce access fs. Default: 256
|
||||||
|
|
||||||
|
config ELF_SYMBOL_CACHECOUNT
|
||||||
|
int "ELF SYMBOL Table Cache Count"
|
||||||
|
default 256
|
||||||
|
---help---
|
||||||
|
This is an cache that is used to store elf symbol table to
|
||||||
reduce access fs. Default: 256
|
reduce access fs. Default: 256
|
||||||
|
|||||||
+116
-45
@@ -74,6 +74,17 @@
|
|||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* REVISIT: This naming breaks the NuttX coding standard, but is consistent
|
||||||
|
* with legacy naming of other ELF32 types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
dq_entry_t entry;
|
||||||
|
Elf32_Sym sym;
|
||||||
|
int idx;
|
||||||
|
} Elf32_SymCache;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -91,8 +102,9 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline int elf_readrels(FAR struct elf_loadinfo_s *loadinfo,
|
static inline int elf_readrels(FAR struct elf_loadinfo_s *loadinfo,
|
||||||
FAR const Elf32_Shdr *relsec,
|
FAR const Elf32_Shdr *relsec,
|
||||||
int index, FAR Elf32_Rel *rels)
|
int index, FAR Elf32_Rel *rels,
|
||||||
|
int count)
|
||||||
{
|
{
|
||||||
off_t offset;
|
off_t offset;
|
||||||
int size;
|
int size;
|
||||||
@@ -108,7 +120,7 @@ static inline int elf_readrels(FAR struct elf_loadinfo_s *loadinfo,
|
|||||||
/* Get the file offset to the symbol table entry */
|
/* Get the file offset to the symbol table entry */
|
||||||
|
|
||||||
offset = sizeof(Elf32_Rel) * index;
|
offset = sizeof(Elf32_Rel) * index;
|
||||||
size = sizeof(Elf32_Rel) * CONFIG_ELF_RELOCATION_BUFFERCOUNT;
|
size = sizeof(Elf32_Rel) * count;
|
||||||
if (offset + size > relsec->sh_size)
|
if (offset + size > relsec->sh_size)
|
||||||
{
|
{
|
||||||
size = relsec->sh_size - offset;
|
size = relsec->sh_size - offset;
|
||||||
@@ -136,24 +148,29 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||||||
FAR const struct symtab_s *exports, int nexports)
|
FAR const struct symtab_s *exports, int nexports)
|
||||||
|
|
||||||
{
|
{
|
||||||
FAR Elf32_Shdr *relsec = &loadinfo->shdr[relidx];
|
FAR Elf32_Shdr *relsec = &loadinfo->shdr[relidx];
|
||||||
FAR Elf32_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
FAR Elf32_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
||||||
FAR Elf32_Rel *rels;
|
FAR Elf32_Rel *rels;
|
||||||
FAR Elf32_Rel *rel;
|
FAR Elf32_Rel *rel;
|
||||||
Elf32_Sym sym;
|
FAR Elf32_SymCache *cache;
|
||||||
FAR Elf32_Sym *psym;
|
FAR Elf32_Sym *sym;
|
||||||
uintptr_t addr;
|
FAR dq_entry_t *e;
|
||||||
int symidx;
|
dq_queue_t q;
|
||||||
int ret;
|
uintptr_t addr;
|
||||||
int i;
|
int symidx;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
rels = kmm_malloc(CONFIG_ELF_RELOCATION_BUFFERCOUNT * sizeof(Elf32_Rel));
|
rels = kmm_malloc(CONFIG_ELF_RELOCATION_BUFFERCOUNT * sizeof(Elf32_Rel));
|
||||||
if (rels == NULL)
|
if (rels == NULL)
|
||||||
{
|
{
|
||||||
berr("Failed to allocate memory for elf relocation rels\n");
|
berr("Failed to allocate memory for elf relocation\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dq_init(&q);
|
||||||
|
|
||||||
/* Examine each relocation in the section. 'relsec' is the section
|
/* Examine each relocation in the section. 'relsec' is the section
|
||||||
* containing the relations. 'dstsec' is the section containing the data
|
* containing the relations. 'dstsec' is the section containing the data
|
||||||
* to be relocated.
|
* to be relocated.
|
||||||
@@ -161,21 +178,20 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||||||
|
|
||||||
ret = OK;
|
ret = OK;
|
||||||
|
|
||||||
for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++)
|
for (i = j = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++)
|
||||||
{
|
{
|
||||||
psym = &sym;
|
|
||||||
|
|
||||||
/* Read the relocation entry into memory */
|
/* Read the relocation entry into memory */
|
||||||
|
|
||||||
rel = &rels[i % CONFIG_ELF_RELOCATION_BUFFERCOUNT];
|
rel = &rels[i % CONFIG_ELF_RELOCATION_BUFFERCOUNT];
|
||||||
|
|
||||||
if (!(i % CONFIG_ELF_RELOCATION_BUFFERCOUNT))
|
if (!(i % CONFIG_ELF_RELOCATION_BUFFERCOUNT))
|
||||||
{
|
{
|
||||||
ret = elf_readrels(loadinfo, relsec, i, rels);
|
ret = elf_readrels(loadinfo, relsec, i, rels,
|
||||||
|
CONFIG_ELF_RELOCATION_BUFFERCOUNT);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
berr("Section %d reloc %d: Failed to read relocation entry: %d\n",
|
berr("Section %d reloc %d: Failed to read relocation entry: %d\n",
|
||||||
relidx, i, ret);
|
relidx, i, ret);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,43 +202,93 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||||||
|
|
||||||
symidx = ELF32_R_SYM(rel->r_info);
|
symidx = ELF32_R_SYM(rel->r_info);
|
||||||
|
|
||||||
/* Read the symbol table entry into memory */
|
/* First try the cache */
|
||||||
|
|
||||||
ret = elf_readsym(loadinfo, symidx, &sym);
|
sym = NULL;
|
||||||
if (ret < 0)
|
for (e = dq_peek(&q); e; e = dq_next(e))
|
||||||
{
|
{
|
||||||
berr("Section %d reloc %d: Failed to read symbol[%d]: %d\n",
|
cache = (FAR Elf32_SymCache *)e;
|
||||||
relidx, i, symidx, ret);
|
if (cache->idx == symidx)
|
||||||
break;
|
{
|
||||||
|
dq_rem(&cache->entry, &q);
|
||||||
|
dq_addfirst(&cache->entry, &q);
|
||||||
|
sym = &cache->sym;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the value of the symbol (in sym.st_value) */
|
/* If the symbol was not found in the cache, we will need to read the
|
||||||
|
* symbol from the file.
|
||||||
|
*/
|
||||||
|
|
||||||
ret = elf_symvalue(loadinfo, &sym, exports, nexports);
|
if (sym == NULL)
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
/* The special error -ESRCH is returned only in one condition: The
|
if (j < CONFIG_ELF_SYMBOL_CACHECOUNT)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
berr("Section %d reloc %d: Undefined symbol[%d] has no name: %d\n",
|
cache = kmm_malloc(sizeof(Elf32_SymCache));
|
||||||
relidx, i, symidx, ret);
|
if (!cache)
|
||||||
psym = NULL;
|
{
|
||||||
|
berr("Failed to allocate memory for elf symbols\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
berr("Section %d reloc %d: Failed to get value of symbol[%d]: %d\n",
|
cache = (FAR Elf32_SymCache *)dq_remlast(&q);
|
||||||
relidx, i, symidx, ret);
|
}
|
||||||
|
|
||||||
|
sym = &cache->sym;
|
||||||
|
|
||||||
|
/* Read the symbol table entry into memory */
|
||||||
|
|
||||||
|
ret = elf_readsym(loadinfo, symidx, sym);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
berr("Section %d reloc %d: Failed to read symbol[%d]: %d\n",
|
||||||
|
relidx, i, symidx, ret);
|
||||||
|
kmm_free(cache);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the value of the symbol (in sym.st_value) */
|
||||||
|
|
||||||
|
ret = elf_symvalue(loadinfo, sym, exports, nexports);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
berr("Section %d reloc %d: Undefined symbol[%d] has no name: %d\n",
|
||||||
|
relidx, i, symidx, ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
berr("Section %d reloc %d: Failed to get value of symbol[%d]: %d\n",
|
||||||
|
relidx, i, symidx, ret);
|
||||||
|
kmm_free(cache);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->idx = symidx;
|
||||||
|
dq_addfirst(&cache->entry, &q);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sym->st_shndx == SHN_UNDEF && sym->st_name == 0)
|
||||||
|
{
|
||||||
|
sym = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the relocation address. */
|
/* Calculate the relocation address. */
|
||||||
@@ -239,7 +305,7 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||||||
|
|
||||||
/* Now perform the architecture-specific relocation */
|
/* Now perform the architecture-specific relocation */
|
||||||
|
|
||||||
ret = up_relocate(rel, psym, addr);
|
ret = up_relocate(rel, sym, addr);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
berr("ERROR: Section %d reloc %d: Relocation failed: %d\n", relidx, i, ret);
|
berr("ERROR: Section %d reloc %d: Relocation failed: %d\n", relidx, i, ret);
|
||||||
@@ -248,6 +314,11 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
kmm_free(rels);
|
kmm_free(rels);
|
||||||
|
while ((e = dq_peek(&q)))
|
||||||
|
{
|
||||||
|
dq_rem(e, &q);
|
||||||
|
kmm_free(e);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,13 @@ config MODLIB_RELOCATION_BUFFERCOUNT
|
|||||||
This is an cache buffer that is used to store elf relocation table to
|
This is an cache buffer that is used to store elf relocation table to
|
||||||
reduce access fs. Default: 256
|
reduce access fs. Default: 256
|
||||||
|
|
||||||
|
config MODLIB_SYMBOL_CACHECOUNT
|
||||||
|
int "MODLIB SYMBOL Table Cache Count"
|
||||||
|
default 256
|
||||||
|
---help---
|
||||||
|
This is an cache that is used to store elf symbol table to
|
||||||
|
reduce access fs. Default: 256
|
||||||
|
|
||||||
if MODLIB_HAVE_SYMTAB
|
if MODLIB_HAVE_SYMTAB
|
||||||
|
|
||||||
config MODLIB_SYMTAB_ARRAY
|
config MODLIB_SYMTAB_ARRAY
|
||||||
|
|||||||
+107
-34
@@ -51,6 +51,21 @@
|
|||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
#include "modlib/modlib.h"
|
#include "modlib/modlib.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* REVISIT: This naming breaks the NuttX coding standard, but is consistent
|
||||||
|
* with legacy naming of other ELF32 types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
dq_entry_t entry;
|
||||||
|
Elf32_Sym sym;
|
||||||
|
int idx;
|
||||||
|
} Elf32_SymCache;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -65,7 +80,8 @@
|
|||||||
|
|
||||||
static inline int modlib_readrels(FAR struct mod_loadinfo_s *loadinfo,
|
static inline int modlib_readrels(FAR struct mod_loadinfo_s *loadinfo,
|
||||||
FAR const Elf32_Shdr *relsec,
|
FAR const Elf32_Shdr *relsec,
|
||||||
int index, FAR Elf32_Rel *rels)
|
int index, FAR Elf32_Rel *rels,
|
||||||
|
int count)
|
||||||
{
|
{
|
||||||
off_t offset;
|
off_t offset;
|
||||||
int size;
|
int size;
|
||||||
@@ -81,7 +97,7 @@ static inline int modlib_readrels(FAR struct mod_loadinfo_s *loadinfo,
|
|||||||
/* Get the file offset to the symbol table entry */
|
/* Get the file offset to the symbol table entry */
|
||||||
|
|
||||||
offset = sizeof(Elf32_Rel) * index;
|
offset = sizeof(Elf32_Rel) * index;
|
||||||
size = sizeof(Elf32_Rel) * CONFIG_MODLIB_RELOCATION_BUFFERCOUNT;
|
size = sizeof(Elf32_Rel) * count;
|
||||||
if (offset + size > relsec->sh_size)
|
if (offset + size > relsec->sh_size)
|
||||||
{
|
{
|
||||||
size = relsec->sh_size - offset;
|
size = relsec->sh_size - offset;
|
||||||
@@ -113,12 +129,15 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||||||
FAR Elf32_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
FAR Elf32_Shdr *dstsec = &loadinfo->shdr[relsec->sh_info];
|
||||||
FAR Elf32_Rel *rels;
|
FAR Elf32_Rel *rels;
|
||||||
FAR Elf32_Rel *rel;
|
FAR Elf32_Rel *rel;
|
||||||
Elf32_Sym sym;
|
FAR Elf32_SymCache *cache;
|
||||||
FAR Elf32_Sym *psym;
|
FAR Elf32_Sym *sym;
|
||||||
|
FAR dq_entry_t *e;
|
||||||
|
dq_queue_t q;
|
||||||
uintptr_t addr;
|
uintptr_t addr;
|
||||||
int symidx;
|
int symidx;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
rels = lib_malloc(CONFIG_MODLIB_RELOCATION_BUFFERCOUNT * sizeof(Elf32_Rel));
|
rels = lib_malloc(CONFIG_MODLIB_RELOCATION_BUFFERCOUNT * sizeof(Elf32_Rel));
|
||||||
if (!rels)
|
if (!rels)
|
||||||
@@ -127,6 +146,8 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dq_init(&q);
|
||||||
|
|
||||||
/* Examine each relocation in the section. 'relsec' is the section
|
/* Examine each relocation in the section. 'relsec' is the section
|
||||||
* containing the relations. 'dstsec' is the section containing the data
|
* containing the relations. 'dstsec' is the section containing the data
|
||||||
* to be relocated.
|
* to be relocated.
|
||||||
@@ -134,17 +155,15 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||||||
|
|
||||||
ret = OK;
|
ret = OK;
|
||||||
|
|
||||||
for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++)
|
for (i = j = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++)
|
||||||
{
|
{
|
||||||
psym = &sym;
|
|
||||||
|
|
||||||
/* Read the relocation entry into memory */
|
/* Read the relocation entry into memory */
|
||||||
|
|
||||||
rel = &rels[i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT];
|
rel = &rels[i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT];
|
||||||
|
|
||||||
if (!(i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT))
|
if (!(i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT))
|
||||||
{
|
{
|
||||||
ret = modlib_readrels(loadinfo, relsec, i, rels);
|
ret = modlib_readrels(loadinfo, relsec, i, rels, CONFIG_MODLIB_RELOCATION_BUFFERCOUNT);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
berr("ERROR: Section %d reloc %d: Failed to read relocation entry: %d\n",
|
berr("ERROR: Section %d reloc %d: Failed to read relocation entry: %d\n",
|
||||||
@@ -159,43 +178,92 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||||||
|
|
||||||
symidx = ELF32_R_SYM(rel->r_info);
|
symidx = ELF32_R_SYM(rel->r_info);
|
||||||
|
|
||||||
/* Read the symbol table entry into memory */
|
/* First try the cache */
|
||||||
|
|
||||||
ret = modlib_readsym(loadinfo, symidx, &sym);
|
sym = NULL;
|
||||||
if (ret < 0)
|
for (e = dq_peek(&q); e; e = dq_next(e))
|
||||||
{
|
{
|
||||||
berr("ERROR: Section %d reloc %d: Failed to read symbol[%d]: %d\n",
|
cache = (FAR Elf32_SymCache *)e;
|
||||||
relidx, i, symidx, ret);
|
if (cache->idx == symidx)
|
||||||
break;
|
{
|
||||||
|
dq_rem(&cache->entry, &q);
|
||||||
|
dq_addfirst(&cache->entry, &q);
|
||||||
|
sym = &cache->sym;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the value of the symbol (in sym.st_value) */
|
/* If the symbol was not found in the cache, we will need to read the
|
||||||
|
* symbol from the file.
|
||||||
|
*/
|
||||||
|
|
||||||
ret = modlib_symvalue(modp, loadinfo, &sym);
|
if (sym == NULL)
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
/* The special error -ESRCH is returned only in one condition: The
|
if (j < CONFIG_MODLIB_SYMBOL_CACHECOUNT)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
berr("ERROR: Section %d reloc %d: Undefined symbol[%d] has no name: %d\n",
|
cache = lib_malloc(sizeof(Elf32_SymCache));
|
||||||
relidx, i, symidx, ret);
|
if (!cache)
|
||||||
psym = NULL;
|
{
|
||||||
|
berr("Failed to allocate memory for elf symbols\n");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
berr("ERROR: Section %d reloc %d: Failed to get value of symbol[%d]: %d\n",
|
cache = (FAR Elf32_SymCache *)dq_remlast(&q);
|
||||||
relidx, i, symidx, ret);
|
}
|
||||||
|
|
||||||
|
sym = &cache->sym;
|
||||||
|
|
||||||
|
/* Read the symbol table entry into memory */
|
||||||
|
|
||||||
|
ret = modlib_readsym(loadinfo, symidx, sym);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
berr("ERROR: Section %d reloc %d: Failed to read symbol[%d]: %d\n",
|
||||||
|
relidx, i, symidx, ret);
|
||||||
|
lib_free(cache);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the value of the symbol (in sym.st_value) */
|
||||||
|
|
||||||
|
ret = modlib_symvalue(modp, loadinfo, sym);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
berr("ERROR: Section %d reloc %d: Undefined symbol[%d] has no name: %d\n",
|
||||||
|
relidx, i, symidx, ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
berr("ERROR: Section %d reloc %d: Failed to get value of symbol[%d]: %d\n",
|
||||||
|
relidx, i, symidx, ret);
|
||||||
|
lib_free(cache);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->idx = symidx;
|
||||||
|
dq_addfirst(&cache->entry, &q);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sym->st_shndx == SHN_UNDEF && sym->st_name == 0)
|
||||||
|
{
|
||||||
|
sym = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the relocation address. */
|
/* Calculate the relocation address. */
|
||||||
@@ -212,7 +280,7 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||||||
|
|
||||||
/* Now perform the architecture-specific relocation */
|
/* Now perform the architecture-specific relocation */
|
||||||
|
|
||||||
ret = up_relocate(rel, psym, addr);
|
ret = up_relocate(rel, sym, addr);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
berr("ERROR: Section %d reloc %d: Relocation failed: %d\n", relidx, i, ret);
|
berr("ERROR: Section %d reloc %d: Relocation failed: %d\n", relidx, i, ret);
|
||||||
@@ -221,6 +289,11 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
lib_free(rels);
|
lib_free(rels);
|
||||||
|
while ((e = dq_peek(&q)))
|
||||||
|
{
|
||||||
|
dq_rem(e, &q);
|
||||||
|
lib_free(e);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user