forked from nuttx/nuttx-update
Add support for the loading of ET_DYN objects
* libs/libc/machine/arm/armv7-m/arch_elf.c - Fix cast of error message parameters * build-globals.sh - Build the modlib_globals.S file used to resolve symbols when dynamically loading * libs/libc/modlib/Make.defs - Build modlib_globals.S for all targets * libs/libc/modlib/modlib_load.c - Calculate sizes and text/data addresses based on program headers rather than section headers - Handle objects with no program headers * libs/libc/modlib/modlib_bind.c - Call modlib_readsym with pointer to symbol table - Add modlib_relocatedyn to manage relocation of symbols with shared object (ET_DYN) - Differentiate between ET_REL and ET_DYN objects - Use arch independent symbol ELF_R_SYM - Cast sizes to avoid warnings * libs/libc/modlib/modlib_load.c - Cast sizes to avoid warnings * include/elf.h - Add definitions that may be found in shared objects * include/nuttx/lib/modlib.h - Add parameter to modlib_readsym prototype - Add prototypes for: - modlib_insertsymtab - modlib_findglobal - Define Elf_Dyn and Elf_Off according to the elf architecture - Add fields to mod_loadifno_s: - Program headers - Exported symbols - Data section address - Padding requirement - Section index for dynamic symbol table - Number of symbols exported - Add prottotype for modlib_freesymtab * libs/libc/dlfcn/lib_dlclose.c - Free the symbol table when the dll is closed * libs/libc/dlfcn/lib_dlopen.c - Add dump of program headers to debug routine - Differentiate between ET_REL and ET_DYN objects * libs/libc/machine/arm/armv7-m/arch_elf.c - Add handling of R_ARM_RELATIVE and R_ARM_JUMP slot relocation types * libs/libc/modlib/modlib_loadshdrs.c - Rename modlib_loadshdrs.c to modlib_loadhdrs.c - Rename modlib_loadshdrs to modlib_loadhdrs - Add code to load program headers * libs/libc/modlib/modlib_symbols.c - Define entry point structure - Add offset parameter to modlib_symname() and use to find symbol names - Add symtab section header parameter to modlib_readsym() - Add offset parameter to modlib_symvalue() to locate symbol names - Add modlib_insertsyntab() to create a symbol table for exporting and resolution - Add findEP() to resolve a symbol in the modlib_global table - Add modlib_findglobal() to find symbol in the modlib_global table - Add modlib_freesymtab() to free the symbol table * libs/libc/modlib/modlib_uninit.c - Free header and sections from a module_loadinfo_s control block * libs/libc/modlib/modlib_verify.c - Handle ET_DYN shared objects * libs/libc/modlib/modlib_globals.S - Multi-target global table - Define library APIs that may be resolved when loading a shared object
This commit is contained in:
parent
f0107683d5
commit
fec789047a
18 changed files with 4918 additions and 140 deletions
149
build-globals.sh
Executable file
149
build-globals.sh
Executable file
|
@ -0,0 +1,149 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Script to create modlib_global.S which contains a structure define
|
||||
# the API names and addresses we will export for resolving symbols in
|
||||
# dynamic loaded shared objects. Typically these are libc APIs.
|
||||
|
||||
#
|
||||
# Find an entrypoint using a binary search
|
||||
#
|
||||
findEP()
|
||||
{
|
||||
CHECK=$1
|
||||
SIZE=${#SYM[@]}
|
||||
L=0
|
||||
R=$((SIZE - 1))
|
||||
while [ ${L} -le ${R} ]
|
||||
do
|
||||
T=$(( L + R ))
|
||||
M=$(( T / 2 ))
|
||||
N=$(( T % 2 ))
|
||||
M=$(( M - N ))
|
||||
if [ ${SYM[${M}]} \< ${CHECK} ]; then
|
||||
L=$(( M + 1 ))
|
||||
elif [ ${SYM[${M}]} = ${CHECK} ]; then
|
||||
return 1
|
||||
else
|
||||
R=$(( M - 1 ))
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# Extract entrypoints from a library after applying a filter to
|
||||
# exclude those we aren't interested in.
|
||||
#
|
||||
getEP()
|
||||
{
|
||||
for ((i = 0; i < ${#OBJ[@]}; i++))
|
||||
do
|
||||
FUNCS=`${NM} -g --defined-only ../staging/${OBJ[$i]} | awk '{print $3}' | sort | grep -Ev ${FILTER}`
|
||||
FUNC=(${FUNCS})
|
||||
for ((j = 0; j < ${#FUNC[@]}; j++))
|
||||
do
|
||||
findEP ${FUNC[$j]}
|
||||
if [ $? -eq 1 ]; then
|
||||
EP[${I_EP}]=${FUNC[$j]}
|
||||
I_EP=$((I_EP + 1))
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# Symbols to ignore within the NuttX libraries
|
||||
#
|
||||
FILTER="^lib_low|^FUNCTION|^STUB|^__start|^_vect|^arm_|^arp_|^bch|^binfmt|^blake|^block_|^cdcacm|^chksum|^clock_|^close_|^crypto_|^devif_|^devnull|^devuran|^devzero|^emerg|^epoll_|^elf_|^_dbgR|^dq_|^env_|^file_|^files_|^fs_|^ftl_|^g_|^get_|^group_|^global|^hcom|^i2c_|^inode_|^iob_|^irq_|^kmm_|^lfs_|^lib_|^local_|^mm_|^modlib_|^mpu_|^mq_|^nGlobals|^net_|^netdev_|^nx|^pipecommon|^posix_spawn_file|^psock_|^ramlog|^rammap|^readline_|^register_|^sched_|^sockfd|^spawn_|^sq_|^stm32|^symtab_|^syslog_|^syslogstream|^task_|^tcp_|^timer_|^uart_|^ub[12]|^udp_|^umm_|^umount|^unload_|^unregister|^up_|^usb|^usrsock_|^watchdog|^wd_"
|
||||
|
||||
#
|
||||
# Extract symbols from the runtime
|
||||
#
|
||||
SYMS=`${NM} ../nuttx | awk '{print $3}' | sort | grep -Ev ${FILTER}`
|
||||
SYM=(${SYMS})
|
||||
GLOBALS="../libs/libc/modlib/modlib_globals.S"
|
||||
I_EP=0
|
||||
|
||||
#
|
||||
# Libraries to be searched
|
||||
#
|
||||
OBJS="libsched.a libdrivers.a libconfigs.a libstubs.a libkc.a libkmm.a libkarch.a libpass1.a libnet.a libcrypto.a libfs.a libbinfmt.a libxx.a libuc.a libumm.a libuarch.a libapps.a"
|
||||
OBJ=(${OBJS})
|
||||
|
||||
#
|
||||
# Perform the extraction from the libraries
|
||||
#
|
||||
getEP
|
||||
EPS=`printf '%s\n' "${EP[@]}" | sort -u`
|
||||
EP=(${EPS})
|
||||
|
||||
#
|
||||
# Generate the modlib_xxxx_globals.S file
|
||||
#
|
||||
GLOBALS="libs/libc/modlib/modlib_${arch}_globals.S"
|
||||
cat >${GLOBALS} <<__EOF__
|
||||
#if __SIZEOF_POINTER__ == 8
|
||||
.macro globalEntry index, ep
|
||||
.weak \p
|
||||
.quad .L\index
|
||||
.quad \ep
|
||||
.endm
|
||||
# define ALIGN 8
|
||||
#else
|
||||
.macro globalEntry index, ep
|
||||
.weak \ep
|
||||
.long .L\index
|
||||
.long \ep
|
||||
.endm
|
||||
# define ALIGN 4
|
||||
#endif
|
||||
#ifdef __ARM_ARCH_ISA_THUMB2
|
||||
# ifdef __ARM_ARCH_7M__
|
||||
.arch armv7e-m
|
||||
# elif defined ___ARM_ARCH 8
|
||||
.arch armv8-m.base
|
||||
#endif
|
||||
#ifdef __ARM_ASM_SYNTAX_UNIFIED__
|
||||
.syntax unified
|
||||
#endif
|
||||
.thumb
|
||||
#endif
|
||||
.data
|
||||
.align ALIGN
|
||||
.global globalNames
|
||||
|
||||
globalNames:
|
||||
__EOF__
|
||||
|
||||
for ((i = 0; i < ${#EP[@]}; i++))
|
||||
do
|
||||
echo ".L${i}: .string \"${EP[$i]}\"" >>${GLOBALS}
|
||||
done
|
||||
|
||||
cat >>${GLOBALS} <<__EOF__
|
||||
.size globalNames, . - globalNames
|
||||
|
||||
.align ${ALIGN}
|
||||
.global nGlobals
|
||||
.type nGlobals, "object"
|
||||
nGlobals:
|
||||
.word ${#EP[@]}
|
||||
.size nGlobals, . - nGlobals
|
||||
|
||||
.align ${ALIGN}
|
||||
.global globalTable
|
||||
.type globalTable, "object"
|
||||
globalTable:
|
||||
__EOF__
|
||||
|
||||
for ((i = 0; i < ${#EP[@]}; i++))
|
||||
do
|
||||
echo " globalEntry ${i}, ${EP[$i]}" >>${GLOBALS}
|
||||
done
|
||||
|
||||
cat >>${GLOBALS} <<__EOF__
|
||||
.size globalTable, . - globalTable
|
||||
__EOF__
|
||||
|
||||
done
|
||||
echo "${#EP[@]} symbols defined"
|
|
@ -214,6 +214,17 @@
|
|||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
|
||||
/* Processor specific values for the Phdr p_type field. */
|
||||
|
||||
#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */
|
||||
|
||||
/* GCC specific */
|
||||
|
||||
#define PT_GNU_EH_FRAME 0x6474e550 /* GCC exception handler frame */
|
||||
#define PT_GNU_STACK 0x6474e551 /* Stack executability */
|
||||
#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
|
||||
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7fffffff
|
||||
|
||||
|
|
|
@ -87,6 +87,14 @@
|
|||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_ARCH_ELF_64BIT
|
||||
typedef Elf64_Off Elf_Off;
|
||||
typedef Elf64_Dyn Elf_Dyn;
|
||||
#else
|
||||
typedef Elf32_Off Elf_Off;
|
||||
typedef Elf32_Dyn Elf_Dyn;
|
||||
#endif
|
||||
|
||||
/* This is the type of the function that is called to uninitialize the
|
||||
* the loaded module. This may mean, for example, un-registering a device
|
||||
* driver. If the module is successfully uninitialized, its memory will be
|
||||
|
@ -198,13 +206,19 @@ struct mod_loadinfo_s
|
|||
size_t dataalign; /* Necessary alignment of .bss/.text */
|
||||
off_t filelen; /* Length of the entire module file */
|
||||
Elf_Ehdr ehdr; /* Buffered module file header */
|
||||
FAR Elf_Phdr *phdr; /* Buffered module program headers */
|
||||
FAR Elf_Shdr *shdr; /* Buffered module section headers */
|
||||
FAR void *exported; /* Module exports */
|
||||
uint8_t *iobuffer; /* File I/O buffer */
|
||||
uintptr_t datasec; /* ET_DYN - data area start from Phdr */
|
||||
uintptr_t segpad; /* Padding between text and data */
|
||||
|
||||
uint16_t symtabidx; /* Symbol table section index */
|
||||
uint16_t strtabidx; /* String table section index */
|
||||
uint16_t dsymtabidx; /* Dynamic symbol table section index */
|
||||
uint16_t buflen; /* size of iobuffer[] */
|
||||
int filfd; /* Descriptor for the file being loaded */
|
||||
int nexports; /* ET_DYN - Number of symbols exported */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -530,4 +544,17 @@ int modlib_registry_verify(FAR struct module_s *modp);
|
|||
|
||||
int modlib_registry_foreach(mod_callback_t callback, FAR void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_freesymtab
|
||||
*
|
||||
* Description:
|
||||
* Free a symbol table for the current module.
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - Module state descriptor
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void modlib_freesymtab(FAR struct module_s *modp);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_LIB_MODLIB_H */
|
||||
|
|
|
@ -142,6 +142,10 @@ static inline int dlremove(FAR void *handle)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Free the modules exported symmbols table */
|
||||
|
||||
modlib_freesymtab(modp);
|
||||
|
||||
/* Remove the module from the registry */
|
||||
|
||||
ret = modlib_registry_del(modp);
|
||||
|
|
|
@ -31,12 +31,14 @@
|
|||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <nuttx/envpath.h>
|
||||
#include <nuttx/module.h>
|
||||
#include <nuttx/lib/modlib.h>
|
||||
|
||||
#include "libc.h"
|
||||
#include "debug.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -98,6 +100,23 @@ static void dldump_loadinfo(FAR struct mod_loadinfo_s *loadinfo)
|
|||
binfo(" sh_entsize: %d\n", shdr->sh_entsize);
|
||||
}
|
||||
}
|
||||
|
||||
if (loadinfo->phdr && loadinfo->ehdr.e_phnum > 0)
|
||||
{
|
||||
for (i = 0; i < loadinfo->ehdr.e_phnum; i++)
|
||||
{
|
||||
FAR Elf32_Phdr *phdr = &loadinfo->phdr[i];
|
||||
binfo("Program Header %d:\n", i);
|
||||
binfo(" p_type: %08x\n", phdr->p_type);
|
||||
binfo(" p_offset: %08x\n", phdr->p_offset);
|
||||
binfo(" p_vaddr: %08x\n", phdr->p_vaddr);
|
||||
binfo(" p_paddr: %08x\n", phdr->p_paddr);
|
||||
binfo(" p_filesz: %08x\n", phdr->p_filesz);
|
||||
binfo(" p_memsz: %08x\n", phdr->p_memsz);
|
||||
binfo(" p_flags: %08x\n", phdr->p_flags);
|
||||
binfo(" p_align: %08x\n", phdr->p_align);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define dldump_loadinfo(i)
|
||||
|
@ -110,6 +129,7 @@ static void dldump_loadinfo(FAR struct mod_loadinfo_s *loadinfo)
|
|||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
#ifdef CONFIG_MODLIB_DUMPBUFFER
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
static void dldump_initializer(mod_initializer_t initializer,
|
||||
FAR struct mod_loadinfo_s *loadinfo)
|
||||
{
|
||||
|
@ -187,6 +207,7 @@ static inline FAR void *dlinsert(FAR const char *filename)
|
|||
binfo("Failed to initialize for load of ELF program: %d\n", ret);
|
||||
goto errout_with_loadinfo;
|
||||
}
|
||||
memset(modp, 0, sizeof(*modp));
|
||||
|
||||
/* Load the program binary */
|
||||
|
||||
|
@ -227,11 +248,14 @@ static inline FAR void *dlinsert(FAR const char *filename)
|
|||
|
||||
/* Call the module initializer */
|
||||
|
||||
ret = initializer(&modp->modinfo);
|
||||
if (ret < 0)
|
||||
if (loadinfo.ehdr.e_type == ET_REL)
|
||||
{
|
||||
binfo("Failed to initialize the module: %d\n", ret);
|
||||
goto errout_with_load;
|
||||
ret = initializer(&modp->modinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
binfo("Failed to initialize the module: %d\n", ret);
|
||||
goto errout_with_load;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the new module entry to the registry */
|
||||
|
|
|
@ -122,7 +122,8 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
|
|||
*/
|
||||
|
||||
relotype = ELF32_R_TYPE(rel->r_info);
|
||||
if (sym == NULL && relotype != R_ARM_NONE && relotype != R_ARM_V4BX)
|
||||
if (sym == NULL && relotype != R_ARM_NONE && relotype != R_ARM_V4BX &&
|
||||
relotype != R_ARM_RELATIVE && relotype != R_ARM_JUMP_SLOT)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -492,6 +493,15 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
|
|||
}
|
||||
break;
|
||||
|
||||
case R_ARM_RELATIVE :
|
||||
case R_ARM_JUMP_SLOT :
|
||||
{
|
||||
binfo("Relocating: RELATIVE/JUMP_SLOT at %p value: %08lx with %08lx\n",
|
||||
(void *)addr,*(unsigned log *) addr, (unsigned long) sym->st_value);
|
||||
*(uint32_t *) addr = (uint32_t) sym->st_value;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
berr("ERROR: Unsupported relocation: %" PRId32 "\n",
|
||||
ELF32_R_TYPE(rel->r_info));
|
||||
|
|
|
@ -23,13 +23,15 @@ ifeq ($(CONFIG_LIBC_MODLIB),y)
|
|||
# Add the nuttx/lib/modlib.h files to the build
|
||||
|
||||
CSRCS += modlib_bind.c modlib_depend.c modlib_init.c modlib_iobuffer.c
|
||||
CSRCS += modlib_load.c modlib_loadshdrs.c
|
||||
CSRCS += modlib_load.c modlib_loadhdrs.c
|
||||
CSRCS += modlib_read.c modlib_registry.c modlib_sections.c
|
||||
CSRCS += modlib_symbols.c modlib_symtab.c modlib_uninit.c modlib_unload.c
|
||||
CSRCS += modlib_verify.c
|
||||
CSRCS += modlib_verify.c
|
||||
|
||||
# Add the modlib directory to the build
|
||||
|
||||
ASRCS += modlib_globals.S
|
||||
|
||||
DEPPATH += --dep-path modlib
|
||||
VPATH += :modlib
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ int modlib_findsymtab(FAR struct mod_loadinfo_s *loadinfo);
|
|||
****************************************************************************/
|
||||
|
||||
int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
||||
FAR Elf_Sym *sym);
|
||||
FAR Elf_Sym *sym, FAR Elf_Shdr *shdr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_symvalue
|
||||
|
@ -110,13 +110,64 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
|||
****************************************************************************/
|
||||
|
||||
int modlib_symvalue(FAR struct module_s *modp,
|
||||
FAR struct mod_loadinfo_s *loadinfo, FAR Elf_Sym *sym);
|
||||
FAR struct mod_loadinfo_s *loadinfo, FAR Elf_Sym *sym,
|
||||
Elf_Off offset);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_insertsymtab
|
||||
*
|
||||
* Description:
|
||||
* Insert a symbol table for the current module.
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - Module state information
|
||||
* loadinfo - Module load information
|
||||
* shdr - Symbol table section header
|
||||
* sym - Symbol table entry
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
* ENOMEM - Symbol undefined and not provided via a symbol table
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int modlib_insertsymtab(FAR struct module_s *modp,
|
||||
FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR Elf_Shdr *shdr,
|
||||
FAR Elf_Sym *sym);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_loadshdrs
|
||||
* Name: modlib_findglobal
|
||||
*
|
||||
* Description:
|
||||
* Loads section headers into memory.
|
||||
* Find a symbol in the global symbol table
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - Module state information
|
||||
* loadinfo - Module load information
|
||||
* shdr - Symbol table section header
|
||||
* sym - Symbol table entry
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
* ENOMEM - Symbol undefined and not provided via a symbol table
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void *modlib_findglobal(FAR struct module_s *modp,
|
||||
FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR Elf_Shdr *shdr,
|
||||
FAR Elf_Sym *sym);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_loadhdrs
|
||||
*
|
||||
* Description:
|
||||
* Loads program and section headers into memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
|
@ -124,7 +175,7 @@ int modlib_symvalue(FAR struct module_s *modp,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int modlib_loadshdrs(FAR struct mod_loadinfo_s *loadinfo);
|
||||
int modlib_loadhdrs(FAR struct mod_loadinfo_s *loadinfo);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_findsection
|
||||
|
|
1119
libs/libc/modlib/modlib_armv7m_globals.S
Normal file
1119
libs/libc/modlib/modlib_armv7m_globals.S
Normal file
File diff suppressed because it is too large
Load diff
|
@ -36,6 +36,14 @@
|
|||
#include "libc.h"
|
||||
#include "modlib/modlib.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define I_REL 0 /* Index into relxxx[] arrays for relocations */
|
||||
#define I_PLT 1 /* ... for PLTs */
|
||||
#define N_RELS 2 /* Number of relxxx[] indexes */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
@ -51,6 +59,16 @@ typedef struct
|
|||
int idx;
|
||||
} Elf_SymCache;
|
||||
|
||||
struct
|
||||
{
|
||||
int strOff; /* Offset to string table */
|
||||
int symOff; /* Offset to symbol table */
|
||||
int lSymTab; /* Size of symbol table */
|
||||
int relEntSz; /* Size of relocation entry */
|
||||
int relOff[2]; /* Offset to the relocation section */
|
||||
int relSz[2]; /* Size of relocation table */
|
||||
} relData;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -245,7 +263,8 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||
|
||||
/* Read the symbol table entry into memory */
|
||||
|
||||
ret = modlib_readsym(loadinfo, symidx, sym);
|
||||
ret = modlib_symvalue(modp, loadinfo, sym,
|
||||
loadinfo->shdr[loadinfo->strtabidx].sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: "
|
||||
|
@ -257,7 +276,8 @@ static int modlib_relocate(FAR struct module_s *modp,
|
|||
|
||||
/* Get the value of the symbol (in sym.st_value) */
|
||||
|
||||
ret = modlib_symvalue(modp, loadinfo, sym);
|
||||
ret = modlib_symvalue(modp, loadinfo, sym,
|
||||
loadinfo->shdr[loadinfo->strtabidx].sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* The special error -ESRCH is returned only in one condition:
|
||||
|
@ -433,7 +453,8 @@ static int modlib_relocateadd(FAR struct module_s *modp,
|
|||
|
||||
/* Read the symbol table entry into memory */
|
||||
|
||||
ret = modlib_readsym(loadinfo, symidx, sym);
|
||||
ret = modlib_readsym(loadinfo, symidx, sym,
|
||||
&loadinfo->shdr[loadinfo->symtabidx]);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: "
|
||||
|
@ -445,7 +466,8 @@ static int modlib_relocateadd(FAR struct module_s *modp,
|
|||
|
||||
/* Get the value of the symbol (in sym.st_value) */
|
||||
|
||||
ret = modlib_symvalue(modp, loadinfo, sym);
|
||||
ret = modlib_symvalue(modp, loadinfo, sym,
|
||||
loadinfo->shdr[loadinfo->strtabidx].sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* The special error -ESRCH is returned only in one condition:
|
||||
|
@ -519,6 +541,230 @@ static int modlib_relocateadd(FAR struct module_s *modp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_relocatedyn
|
||||
*
|
||||
* Description:
|
||||
* Perform all relocations associated with a dynamic section.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int modlib_relocatedyn(FAR struct module_s *modp,
|
||||
FAR struct mod_loadinfo_s *loadinfo,
|
||||
int relidx)
|
||||
{
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[relidx];
|
||||
FAR Elf_Shdr *symhdr;
|
||||
FAR Elf_Dyn *dyn = NULL;
|
||||
FAR Elf_Rel *rels = NULL;
|
||||
FAR Elf_Rel *rel;
|
||||
FAR Elf_Sym *sym = NULL;
|
||||
uintptr_t addr;
|
||||
int ret;
|
||||
int i;
|
||||
int idx_rel;
|
||||
int idx_sym;
|
||||
|
||||
dyn = lib_malloc(shdr->sh_size);
|
||||
ret = modlib_read(loadinfo, (FAR uint8_t *) dyn, shdr->sh_size,
|
||||
shdr->sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("Failed to read dynamic section header");
|
||||
return ret;
|
||||
}
|
||||
|
||||
rels = lib_malloc(CONFIG_MODLIB_RELOCATION_BUFFERCOUNT * sizeof(Elf_Rel));
|
||||
if (!rels)
|
||||
{
|
||||
berr("Failed to allocate memory for elf relocation rels\n");
|
||||
lib_free(dyn);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset((void *) &relData, 0, sizeof(relData));
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; i++)
|
||||
{
|
||||
switch (dyn[i].d_tag)
|
||||
{
|
||||
case DT_REL :
|
||||
relData.relOff[I_REL] = dyn[i].d_un.d_val;
|
||||
break;
|
||||
case DT_RELSZ :
|
||||
relData.relSz[I_REL] = dyn[i].d_un.d_val;
|
||||
break;
|
||||
case DT_RELENT :
|
||||
relData.relEntSz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
case DT_SYMTAB :
|
||||
relData.symOff = dyn[i].d_un.d_val;
|
||||
break;
|
||||
case DT_STRTAB :
|
||||
relData.strOff = dyn[i].d_un.d_val;
|
||||
break;
|
||||
case DT_JMPREL :
|
||||
relData.relOff[I_PLT] = dyn[i].d_un.d_val;
|
||||
break;
|
||||
case DT_PLTRELSZ :
|
||||
relData.relSz[I_PLT] = dyn[i].d_un.d_val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
symhdr = &loadinfo->shdr[loadinfo->dsymtabidx];
|
||||
sym = lib_malloc(symhdr->sh_size);
|
||||
if (!sym)
|
||||
{
|
||||
berr("Error obtaining storage for dynamic symbol table");
|
||||
lib_free(rels);
|
||||
lib_free(dyn);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = modlib_read(loadinfo, (uint8_t *) sym, symhdr->sh_size,
|
||||
symhdr->sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("Error reading dynamic symbol table - %d", ret);
|
||||
lib_free(sym);
|
||||
lib_free(rels);
|
||||
lib_free(dyn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
relData.lSymTab = relData.strOff - relData.symOff;
|
||||
|
||||
for (idx_rel = 0; idx_rel < N_RELS; idx_rel++)
|
||||
{
|
||||
if (relData.relOff[idx_rel] == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Examine each relocation in the .rel.* section. */
|
||||
|
||||
ret = OK;
|
||||
|
||||
for (i = 0; i < relData.relSz[idx_rel] / relData.relEntSz; i++)
|
||||
{
|
||||
/* Process each relocation entry */
|
||||
|
||||
rel = &rels[i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT];
|
||||
|
||||
if (!(i % CONFIG_MODLIB_RELOCATION_BUFFERCOUNT))
|
||||
{
|
||||
ret = modlib_read(loadinfo, (FAR uint8_t *) rels,
|
||||
sizeof(Elf_Rel) * CONFIG_MODLIB_RELOCATION_BUFFERCOUNT,
|
||||
relData.relOff[idx_rel] +
|
||||
i * sizeof(Elf_Rel));
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d:"
|
||||
"Failed to read relocation entry: %d\n",
|
||||
relidx, i, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the relocation address. */
|
||||
|
||||
if (rel->r_offset < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d:"
|
||||
"Relocation address out of range, offset %u\n",
|
||||
relidx, i, (int) rel->r_offset);
|
||||
ret = -EINVAL;
|
||||
lib_free(sym);
|
||||
lib_free(rels);
|
||||
lib_free(dyn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Now perform the architecture-specific relocation */
|
||||
|
||||
if ((idx_sym = ELF_R_SYM(rel->r_info)) != 0)
|
||||
{
|
||||
if (sym[idx_sym].st_shndx == SHN_UNDEF) /* We have an external reference */
|
||||
{
|
||||
void *ep;
|
||||
|
||||
ep = modlib_findglobal(modp, loadinfo, symhdr,
|
||||
&sym[idx_sym]);
|
||||
if (ep == NULL)
|
||||
{
|
||||
berr("ERROR: Unable to resolve addr of ext ref %s\n",
|
||||
loadinfo->iobuffer);
|
||||
ret = -EINVAL;
|
||||
lib_free(sym);
|
||||
lib_free(rels);
|
||||
lib_free(dyn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
addr = rel->r_offset + loadinfo->textalloc;
|
||||
*(uintptr_t *)addr = (uintptr_t)ep;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Elf_Sym dynSym;
|
||||
|
||||
addr = rel->r_offset - loadinfo->datasec + loadinfo->datastart;
|
||||
|
||||
if ((*(uint32_t *) addr) < loadinfo->datasec)
|
||||
dynSym.st_value = *(uint32_t *) addr + loadinfo->textalloc;
|
||||
else
|
||||
dynSym.st_value = *(uint32_t *) addr -
|
||||
loadinfo->datasec + loadinfo->datastart;
|
||||
ret = up_relocate(rel, &dynSym, addr);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Section %d reloc %d: Relocation failed: %d\n",
|
||||
relidx, i, ret);
|
||||
lib_free(sym);
|
||||
lib_free(rels);
|
||||
lib_free(dyn);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate through the dynamic symbol table looking for global symbols to
|
||||
* put in our own symbol table for use with dlgetsym()
|
||||
*/
|
||||
|
||||
/* Relocate the entries in the table */
|
||||
|
||||
for (i = 0; i < (symhdr->sh_size / sizeof(Elf_Sym)); i++)
|
||||
{
|
||||
Elf_Shdr *s = &loadinfo->shdr[sym[i].st_shndx];
|
||||
|
||||
if (sym[i].st_shndx != SHN_UNDEF)
|
||||
{
|
||||
if (s->sh_addr < loadinfo->datasec)
|
||||
sym[i].st_value = sym[i].st_value + loadinfo->textalloc;
|
||||
else
|
||||
sym[i].st_value = sym[i].st_value -
|
||||
loadinfo->datasec + loadinfo->datastart;
|
||||
}
|
||||
}
|
||||
|
||||
ret = modlib_insertsymtab(modp, loadinfo, symhdr, sym);
|
||||
|
||||
lib_free(sym);
|
||||
lib_free(rels);
|
||||
lib_free(dyn);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -578,24 +824,40 @@ int modlib_bind(FAR struct module_s *modp,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Make sure that the section is allocated. We can't relocate
|
||||
* sections that were not loaded into memory.
|
||||
*/
|
||||
|
||||
if ((loadinfo->shdr[infosec].sh_flags & SHF_ALLOC) == 0)
|
||||
if (loadinfo->ehdr.e_type == ET_DYN)
|
||||
{
|
||||
continue;
|
||||
switch (loadinfo->shdr[i].sh_type)
|
||||
{
|
||||
case SHT_DYNAMIC :
|
||||
ret = modlib_relocatedyn(modp, loadinfo, i);
|
||||
break;
|
||||
case SHT_DYNSYM :
|
||||
loadinfo->dsymtabidx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process the relocations by type */
|
||||
|
||||
if (loadinfo->shdr[i].sh_type == SHT_REL)
|
||||
else
|
||||
{
|
||||
ret = modlib_relocate(modp, loadinfo, i);
|
||||
}
|
||||
else if (loadinfo->shdr[i].sh_type == SHT_RELA)
|
||||
{
|
||||
ret = modlib_relocateadd(modp, loadinfo, i);
|
||||
/* Make sure that the section is allocated. We can't relocate
|
||||
* sections that were not loaded into memory.
|
||||
*/
|
||||
|
||||
if ((loadinfo->shdr[i].sh_flags & SHF_ALLOC) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Process the relocations by type */
|
||||
|
||||
switch (loadinfo->shdr[i].sh_type)
|
||||
{
|
||||
case SHT_REL :
|
||||
ret = modlib_relocate(modp, loadinfo, i);
|
||||
break;
|
||||
case SHT_RELA :
|
||||
ret = modlib_relocateadd(modp, loadinfo, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
|
1145
libs/libc/modlib/modlib_globals.S
Normal file
1145
libs/libc/modlib/modlib_globals.S
Normal file
File diff suppressed because it is too large
Load diff
|
@ -79,36 +79,63 @@ static void modlib_elfsize(struct mod_loadinfo_s *loadinfo)
|
|||
textsize = 0;
|
||||
datasize = 0;
|
||||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
if (loadinfo->ehdr.e_phnum > 0)
|
||||
{
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution.
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_ALLOC) != 0)
|
||||
for (i = 0; i < loadinfo->ehdr.e_phnum; i++)
|
||||
{
|
||||
/* SHF_WRITE indicates that the section address space is write-
|
||||
* able
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||
FAR Elf_Phdr *phdr = &loadinfo->phdr[i];
|
||||
FAR void *textaddr = NULL;
|
||||
|
||||
if (phdr->p_type == PT_LOAD)
|
||||
{
|
||||
datasize = _ALIGN_UP(datasize, shdr->sh_addralign);
|
||||
datasize += ELF_ALIGNUP(shdr->sh_size);
|
||||
if (loadinfo->dataalign < shdr->sh_addralign)
|
||||
if (phdr->p_flags & PF_X)
|
||||
{
|
||||
loadinfo->dataalign = shdr->sh_addralign;
|
||||
textsize += phdr->p_memsz;
|
||||
textaddr = (void *) phdr->p_vaddr;
|
||||
}
|
||||
else
|
||||
{
|
||||
datasize += phdr->p_memsz;
|
||||
loadinfo->datasec = phdr->p_vaddr;
|
||||
loadinfo->segpad = phdr->p_vaddr -
|
||||
((uintptr_t) textaddr + textsize);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution.
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_ALLOC) != 0)
|
||||
{
|
||||
textsize = _ALIGN_UP(textsize, shdr->sh_addralign);
|
||||
textsize += ELF_ALIGNUP(shdr->sh_size);
|
||||
if (loadinfo->textalign < shdr->sh_addralign)
|
||||
/* SHF_WRITE indicates that the section address space is write-
|
||||
* able
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||
{
|
||||
loadinfo->textalign = shdr->sh_addralign;
|
||||
datasize = _ALIGN_UP(datasize, shdr->sh_addralign);
|
||||
datasize += ELF_ALIGNUP(shdr->sh_size);
|
||||
if (loadinfo->dataalign < shdr->sh_addralign)
|
||||
{
|
||||
loadinfo->dataalign = shdr->sh_addralign;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
textsize = _ALIGN_UP(textsize, shdr->sh_addralign);
|
||||
textsize += ELF_ALIGNUP(shdr->sh_size);
|
||||
if (loadinfo->textalign < shdr->sh_addralign)
|
||||
{
|
||||
loadinfo->textalign = shdr->sh_addralign;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,75 +168,110 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo)
|
|||
int ret;
|
||||
int i;
|
||||
|
||||
/* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */
|
||||
/* Read each PT_LOAD area into memory */
|
||||
|
||||
binfo("Loaded sections:\n");
|
||||
binfo("Loading sections - text: %p.%x data: %p.%x\n",
|
||||
(void *)loadinfo->textalloc, (int) loadinfo->textsize,
|
||||
(void *)loadinfo->datastart, (int) loadinfo->datasize);
|
||||
text = (FAR uint8_t *)loadinfo->textalloc;
|
||||
data = (FAR uint8_t *)loadinfo->datastart;
|
||||
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
if (loadinfo->ehdr.e_phnum > 0)
|
||||
{
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_ALLOC) == 0)
|
||||
for (i = 0; i < loadinfo->ehdr.e_phnum; i++)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* SHF_WRITE indicates that the section address space is write-
|
||||
* able
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||
{
|
||||
pptr = &data;
|
||||
}
|
||||
else
|
||||
{
|
||||
pptr = &text;
|
||||
}
|
||||
|
||||
*pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr, shdr->sh_addralign);
|
||||
|
||||
/* SHT_NOBITS indicates that there is no data in the file for the
|
||||
* section.
|
||||
*/
|
||||
|
||||
if (shdr->sh_type != SHT_NOBITS)
|
||||
{
|
||||
/* Read the section data from sh_offset to the memory region */
|
||||
|
||||
ret = modlib_read(loadinfo, *pptr, shdr->sh_size, shdr->sh_offset);
|
||||
if (ret < 0)
|
||||
FAR Elf_Phdr *phdr = &loadinfo->phdr[i];
|
||||
|
||||
if (phdr->p_type == PT_LOAD)
|
||||
{
|
||||
berr("ERROR: Failed to read section %d: %d\n", i, ret);
|
||||
return ret;
|
||||
if (phdr->p_flags & PF_X)
|
||||
{
|
||||
ret = modlib_read(loadinfo, text, phdr->p_filesz,
|
||||
phdr->p_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
int bssSize = phdr->p_memsz - phdr->p_filesz;
|
||||
ret = modlib_read(loadinfo, data, phdr->p_filesz,
|
||||
phdr->p_offset);
|
||||
memset((FAR void *)((uintptr_t) data + phdr->p_filesz), 0,
|
||||
bssSize);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Failed to read section %d: %d\n", i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is no data in an allocated section, then the allocated
|
||||
* section must be cleared.
|
||||
*/
|
||||
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||
{
|
||||
memset(*pptr, 0, shdr->sh_size);
|
||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||
|
||||
/* SHF_ALLOC indicates that the section requires memory during
|
||||
* execution
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_ALLOC) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* SHF_WRITE indicates that the section address space is write-
|
||||
* able
|
||||
*/
|
||||
|
||||
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||
{
|
||||
pptr = &data;
|
||||
}
|
||||
else
|
||||
{
|
||||
pptr = &text;
|
||||
}
|
||||
|
||||
*pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr, shdr->sh_addralign);
|
||||
|
||||
/* SHT_NOBITS indicates that there is no data in the file for the
|
||||
* section.
|
||||
*/
|
||||
|
||||
if (shdr->sh_type != SHT_NOBITS)
|
||||
{
|
||||
/* Read the section data from sh_offset to the memory region */
|
||||
|
||||
ret = modlib_read(loadinfo, *pptr, shdr->sh_size, shdr->sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Failed to read section %d: %d\n", i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is no data in an allocated section, then the allocated
|
||||
* section must be cleared.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
memset(*pptr, 0, shdr->sh_size);
|
||||
}
|
||||
|
||||
/* Update sh_addr to point to copy in memory */
|
||||
|
||||
binfo("%d. %08lx->%08lx\n", i,
|
||||
(unsigned long)shdr->sh_addr, (unsigned long)*pptr);
|
||||
|
||||
shdr->sh_addr = (uintptr_t)*pptr;
|
||||
|
||||
/* Setup the memory pointer for the next time through the loop */
|
||||
|
||||
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
||||
}
|
||||
|
||||
/* Update sh_addr to point to copy in memory */
|
||||
|
||||
binfo("%d. %08lx->%08lx\n", i,
|
||||
(unsigned long)shdr->sh_addr, (unsigned long)*pptr);
|
||||
|
||||
shdr->sh_addr = (uintptr_t)*pptr;
|
||||
|
||||
/* Setup the memory pointer for the next time through the loop */
|
||||
|
||||
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -239,12 +301,12 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
|
|||
binfo("loadinfo: %p\n", loadinfo);
|
||||
DEBUGASSERT(loadinfo && loadinfo->filfd >= 0);
|
||||
|
||||
/* Load section headers into memory */
|
||||
/* Load section and program headers into memory */
|
||||
|
||||
ret = modlib_loadshdrs(loadinfo);
|
||||
ret = modlib_loadhdrs(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: modlib_loadshdrs failed: %d\n", ret);
|
||||
berr("ERROR: modlib_loadhdrs failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
|
@ -261,10 +323,14 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
|
|||
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
||||
loadinfo->textalloc = (uintptr_t)
|
||||
up_textheap_memalign(loadinfo->textalign,
|
||||
loadinfo->textsize);
|
||||
loadinfo->textsize +
|
||||
loadinfo->datasize +
|
||||
loadinfo->segpad);
|
||||
#else
|
||||
loadinfo->textalloc = (uintptr_t)lib_memalign(loadinfo->textalign,
|
||||
loadinfo->textsize);
|
||||
loadinfo->textsize +
|
||||
loadinfo->datasize +
|
||||
loadinfo->segpad);
|
||||
#endif
|
||||
if (!loadinfo->textalloc)
|
||||
{
|
||||
|
@ -276,14 +342,9 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
|
|||
|
||||
if (loadinfo->datasize > 0)
|
||||
{
|
||||
loadinfo->datastart = (uintptr_t)lib_memalign(loadinfo->dataalign,
|
||||
loadinfo->datasize);
|
||||
if (!loadinfo->datastart)
|
||||
{
|
||||
berr("ERROR: Failed to allocate memory for the module data\n");
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
loadinfo->datastart = loadinfo->textalloc +
|
||||
loadinfo->textsize +
|
||||
loadinfo->segpad;
|
||||
}
|
||||
|
||||
/* Load ELF section data into memory */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* libs/libc/modlib/modlib_loadshdrs.c
|
||||
* libs/libc/modlib/modlib_loadhdrs.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
@ -42,10 +42,10 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_loadshdrs
|
||||
* Name: modlib_loadhdrs
|
||||
*
|
||||
* Description:
|
||||
* Loads section headers into memory.
|
||||
* Loads program and section headers into memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
|
@ -53,12 +53,14 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int modlib_loadshdrs(FAR struct mod_loadinfo_s *loadinfo)
|
||||
int modlib_loadhdrs(FAR struct mod_loadinfo_s *loadinfo)
|
||||
{
|
||||
size_t shdrsize;
|
||||
size_t phdrsize;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(loadinfo->shdr == NULL);
|
||||
DEBUGASSERT(loadinfo->phdr == NULL);
|
||||
|
||||
/* Verify that there are sections */
|
||||
|
||||
|
@ -68,6 +70,14 @@ int modlib_loadshdrs(FAR struct mod_loadinfo_s *loadinfo)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Verify that there are program headers */
|
||||
|
||||
if (loadinfo->ehdr.e_phnum < 1)
|
||||
{
|
||||
berr("ERROR: No program headers(?)\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get the total size of the section header table */
|
||||
|
||||
shdrsize = (size_t)loadinfo->ehdr.e_shentsize *
|
||||
|
@ -78,6 +88,16 @@ int modlib_loadshdrs(FAR struct mod_loadinfo_s *loadinfo)
|
|||
return -ESPIPE;
|
||||
}
|
||||
|
||||
/* Get the total size of the program header table */
|
||||
|
||||
phdrsize = (size_t)loadinfo->ehdr.e_phentsize *
|
||||
(size_t)loadinfo->ehdr.e_phnum;
|
||||
if (loadinfo->ehdr.e_phoff + phdrsize > loadinfo->filelen)
|
||||
{
|
||||
berr("ERROR: Insufficent space in file for program header table\n");
|
||||
return -ESPIPE;
|
||||
}
|
||||
|
||||
/* Allocate memory to hold a working copy of the sector header table */
|
||||
|
||||
loadinfo->shdr = (FAR FAR Elf_Shdr *)lib_malloc(shdrsize);
|
||||
|
@ -97,5 +117,27 @@ int modlib_loadshdrs(FAR struct mod_loadinfo_s *loadinfo)
|
|||
berr("ERROR: Failed to read section header table: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Allocate memory to hold a working copy of the program header table */
|
||||
|
||||
loadinfo->phdr = (FAR FAR Elf_Phdr *)lib_malloc(phdrsize);
|
||||
if (!loadinfo->shdr)
|
||||
{
|
||||
lib_free((FAR void *)loadinfo->shdr);
|
||||
berr("ERROR: Failed to allocate the program header table. Size: %ld\n",
|
||||
(long)phdrsize);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Read the program header table into memory */
|
||||
|
||||
ret = modlib_read(loadinfo, (FAR uint8_t *)loadinfo->phdr, phdrsize,
|
||||
loadinfo->ehdr.e_phoff);
|
||||
if (ret < 0)
|
||||
{
|
||||
berr("ERROR: Failed to read program header table: %d\n", ret);
|
||||
lib_free((FAR void *)loadinfo->phdr);
|
||||
lib_free((FAR void *)loadinfo->shdr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <nuttx/lib/modlib.h>
|
||||
|
||||
#include "libc.h"
|
||||
#include "modlib/modlib.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -55,6 +56,12 @@ struct mod_exportinfo_s
|
|||
FAR const struct symtab_s *symbol; /* Symbol info returned (if found) */
|
||||
};
|
||||
|
||||
struct epTable_s
|
||||
{
|
||||
uint8_t *epName; /* Name of global symbol */
|
||||
void *epAddr; /* Address of global symbol */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -76,7 +83,7 @@ struct mod_exportinfo_s
|
|||
****************************************************************************/
|
||||
|
||||
static int modlib_symname(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR const Elf_Sym *sym)
|
||||
FAR const Elf_Sym *sym, Elf_Off sh_offset)
|
||||
{
|
||||
FAR uint8_t *buffer;
|
||||
off_t offset;
|
||||
|
@ -94,7 +101,7 @@ static int modlib_symname(FAR struct mod_loadinfo_s *loadinfo,
|
|||
return -ESRCH;
|
||||
}
|
||||
|
||||
offset = loadinfo->shdr[loadinfo->strtabidx].sh_offset + sym->st_name;
|
||||
offset = sh_offset + sym->st_name;
|
||||
|
||||
/* Loop until we get the entire symbol name into memory */
|
||||
|
||||
|
@ -145,6 +152,8 @@ static int modlib_symname(FAR struct mod_loadinfo_s *loadinfo,
|
|||
berr("ERROR: mod_reallocbuffer failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
offset += CONFIG_MODLIB_BUFFERINCR;
|
||||
}
|
||||
|
||||
/* We will not get here */
|
||||
|
@ -258,9 +267,8 @@ int modlib_findsymtab(FAR struct mod_loadinfo_s *loadinfo)
|
|||
****************************************************************************/
|
||||
|
||||
int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
||||
FAR Elf_Sym *sym)
|
||||
FAR Elf_Sym *sym, FAR Elf_Shdr *symtab)
|
||||
{
|
||||
FAR Elf_Shdr *symtab = &loadinfo->shdr[loadinfo->symtabidx];
|
||||
off_t offset;
|
||||
|
||||
/* Verify that the symbol table index lies within symbol table */
|
||||
|
@ -288,9 +296,10 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
|||
* in the st_value field of the symbol table entry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - Module state information
|
||||
* loadinfo - Load state information
|
||||
* sym - Symbol table entry (value might be undefined)
|
||||
* modp - Module state information
|
||||
* loadinfo - Load state information
|
||||
* sym - Symbol table entry (value might be undefined)
|
||||
* sh_offset - Offset of strtab
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
|
@ -305,7 +314,8 @@ int modlib_readsym(FAR struct mod_loadinfo_s *loadinfo, int index,
|
|||
****************************************************************************/
|
||||
|
||||
int modlib_symvalue(FAR struct module_s *modp,
|
||||
FAR struct mod_loadinfo_s *loadinfo, FAR Elf_Sym *sym)
|
||||
FAR struct mod_loadinfo_s *loadinfo, FAR Elf_Sym *sym,
|
||||
Elf_Off sh_offset)
|
||||
{
|
||||
FAR const struct symtab_s *symbol;
|
||||
struct mod_exportinfo_s exportinfo;
|
||||
|
@ -335,7 +345,7 @@ int modlib_symvalue(FAR struct module_s *modp,
|
|||
{
|
||||
/* Get the name of the undefined symbol */
|
||||
|
||||
ret = modlib_symname(loadinfo, sym);
|
||||
ret = modlib_symname(loadinfo, sym, sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* There are a few relocations for a few architectures that do
|
||||
|
@ -406,7 +416,8 @@ int modlib_symvalue(FAR struct module_s *modp,
|
|||
{
|
||||
secbase = loadinfo->shdr[sym->st_shndx].sh_addr;
|
||||
|
||||
binfo("Other: %08" PRIxPTR "+%08" PRIxPTR "=%08" PRIxPTR "\n",
|
||||
binfo("Other[%d]: %08" PRIxPTR "+%08" PRIxPTR "=%08" PRIxPTR "\n",
|
||||
sym->st_shndx,
|
||||
(uintptr_t)sym->st_value, secbase,
|
||||
(uintptr_t)(sym->st_value + secbase));
|
||||
|
||||
|
@ -417,3 +428,173 @@ int modlib_symvalue(FAR struct module_s *modp,
|
|||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_insertsymtab
|
||||
*
|
||||
* Description:
|
||||
* Insert a symbol into the modules exportinfo array.
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - Module state information
|
||||
* loadinfo - Load state information
|
||||
* shdr - Symbol table section header
|
||||
* sym - Symbol table entry
|
||||
*
|
||||
* Returned Value:
|
||||
* 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).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int modlib_insertsymtab(FAR struct module_s *modp,
|
||||
struct mod_loadinfo_s *loadinfo,
|
||||
FAR Elf_Shdr *shdr, FAR Elf_Sym *sym)
|
||||
{
|
||||
FAR struct symtab_s *symbol;
|
||||
FAR Elf_Shdr *strTab = &loadinfo->shdr[shdr->sh_link];
|
||||
int ret = 0;
|
||||
int i;
|
||||
int j;
|
||||
int nSym;
|
||||
int symCount;
|
||||
|
||||
if (modp->modinfo.exports != NULL)
|
||||
{
|
||||
bwarn("Module export information already present - replacing");
|
||||
modlib_freesymtab((FAR void *) modp);
|
||||
}
|
||||
|
||||
/* Count the "live" symbols */
|
||||
|
||||
nSym = shdr->sh_size / sizeof(Elf_Sym);
|
||||
for (i = 0, symCount = 0; i < nSym; i++)
|
||||
{
|
||||
if (sym[i].st_name != 0)
|
||||
symCount++;
|
||||
}
|
||||
|
||||
if (symCount > 0)
|
||||
{
|
||||
modp->modinfo.exports = symbol =
|
||||
loadinfo->exported =
|
||||
lib_malloc(sizeof(*symbol) * symCount);
|
||||
if (modp->modinfo.exports)
|
||||
{
|
||||
/* Build out module's symbol table */
|
||||
|
||||
modp->modinfo.nexports = symCount;
|
||||
for (i = 0, j = 0; i < nSym; i++)
|
||||
{
|
||||
if (sym[i].st_name != 0)
|
||||
{
|
||||
ret = modlib_symname(loadinfo, &sym[i], strTab->sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
lib_free((FAR void *) modp->modinfo.exports);
|
||||
modp->modinfo.exports = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
symbol[j].sym_name = strdup((char *) loadinfo->iobuffer);
|
||||
symbol[j].sym_value = (FAR const void *) sym[i].st_value;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
berr("Unable to get memory for exported symbols table");
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: findEP
|
||||
*
|
||||
* Description:
|
||||
* Binary search comparison function
|
||||
*
|
||||
* Input Parameters:
|
||||
* c1 - Comparand 1
|
||||
* c2 - Comparand 2
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int findEP(const void *c1, const void *c2)
|
||||
{
|
||||
const struct epTable_s *m1 = (struct epTable_s *) c1;
|
||||
const struct epTable_s *m2 = (struct epTable_s *) c2;
|
||||
return strcmp((FAR const char *)m1->epName, (FAR const char *)m2->epName);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_findglobal
|
||||
*
|
||||
* Description:
|
||||
* Find a symbol in our library entry point table
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - Module state information
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void *modlib_findglobal(FAR struct module_s *modp,
|
||||
struct mod_loadinfo_s *loadinfo,
|
||||
FAR Elf_Shdr *shdr, FAR Elf_Sym *sym)
|
||||
{
|
||||
FAR Elf_Shdr *strTab = &loadinfo->shdr[shdr->sh_link];
|
||||
int ret;
|
||||
struct epTable_s key;
|
||||
struct epTable_s *res;
|
||||
extern struct epTable_s globalTable[];
|
||||
extern int nGlobals;
|
||||
|
||||
ret = modlib_symname(loadinfo, sym, strTab->sh_offset);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
key.epName = loadinfo->iobuffer;
|
||||
res = bsearch(&key, globalTable, nGlobals,
|
||||
sizeof(struct epTable_s), findEP);
|
||||
if (res != NULL)
|
||||
{
|
||||
return res->epAddr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: modlib_freesymtab
|
||||
*
|
||||
* Description:
|
||||
* Free a symbol table
|
||||
*
|
||||
* Input Parameters:
|
||||
* modp - Module state information
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void modlib_freesymtab(FAR struct module_s *modp)
|
||||
{
|
||||
FAR const struct symtab_s *symbol;
|
||||
|
||||
if ((symbol = modp->modinfo.exports))
|
||||
{
|
||||
for (int i = 0; i < modp->modinfo.nexports; i++)
|
||||
{
|
||||
lib_free((FAR void *) symbol[i].sym_name);
|
||||
}
|
||||
|
||||
lib_free((FAR void *) symbol);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,12 @@ int modlib_freebuffers(struct mod_loadinfo_s *loadinfo)
|
|||
loadinfo->shdr = NULL;
|
||||
}
|
||||
|
||||
if (loadinfo->phdr != NULL)
|
||||
{
|
||||
lib_free((FAR void *)loadinfo->phdr);
|
||||
loadinfo->phdr = NULL;
|
||||
}
|
||||
|
||||
if (loadinfo->iobuffer != NULL)
|
||||
{
|
||||
lib_free((FAR void *)loadinfo->iobuffer);
|
||||
|
|
|
@ -84,8 +84,11 @@ int modlib_verifyheader(FAR const Elf_Ehdr *ehdr)
|
|||
|
||||
if (ehdr->e_type != ET_REL)
|
||||
{
|
||||
berr("ERROR: Not a relocatable file: e_type=%d\n", ehdr->e_type);
|
||||
return -EINVAL;
|
||||
if (ehdr->e_type != ET_DYN)
|
||||
{
|
||||
berr("ERROR: Not a relocatable file: e_type=%d\n", ehdr->e_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify that this file works with the currently configured architecture */
|
||||
|
|
1116
libs/libc/modlib/modlib_x32_globals.S
Normal file
1116
libs/libc/modlib/modlib_x32_globals.S
Normal file
File diff suppressed because it is too large
Load diff
565
libs/libc/modlib/modlib_x64_globals.S
Normal file
565
libs/libc/modlib/modlib_x64_globals.S
Normal file
|
@ -0,0 +1,565 @@
|
|||
.data
|
||||
.align 8
|
||||
.global globalNames
|
||||
|
||||
globalNames:
|
||||
.L0: .string "accept4"
|
||||
.L1: .string "clearenv"
|
||||
.L2: .string "cmd_alias"
|
||||
.L3: .string "cmd_arp"
|
||||
.L4: .string "cmd_basename"
|
||||
.L5: .string "cmd_break"
|
||||
.L6: .string "cmd_cat"
|
||||
.L7: .string "cmd_cd"
|
||||
.L8: .string "cmd_cmp"
|
||||
.L9: .string "cmd_cp"
|
||||
.L10: .string "cmd_date"
|
||||
.L11: .string "cmd_dd"
|
||||
.L12: .string "cmd_dirname"
|
||||
.L13: .string "cmd_dmesg"
|
||||
.L14: .string "cmd_echo"
|
||||
.L15: .string "cmd_exec"
|
||||
.L16: .string "cmd_hexdump"
|
||||
.L17: .string "cmd_insmod"
|
||||
.L18: .string "cmd_kill"
|
||||
.L19: .string "cmd_lbracket"
|
||||
.L20: .string "cmd_losetup"
|
||||
.L21: .string "cmd_ls"
|
||||
.L22: .string "cmd_mkdir"
|
||||
.L23: .string "cmd_mkfifo"
|
||||
.L24: .string "cmd_mkrd"
|
||||
.L25: .string "cmd_mount"
|
||||
.L26: .string "cmd_mv"
|
||||
.L27: .string "cmd_nslookup"
|
||||
.L28: .string "cmd_poweroff"
|
||||
.L29: .string "cmd_printf"
|
||||
.L30: .string "cmd_pwd"
|
||||
.L31: .string "cmd_rm"
|
||||
.L32: .string "cmd_rmdir"
|
||||
.L33: .string "cmd_rmmod"
|
||||
.L34: .string "cmd_set"
|
||||
.L35: .string "cmd_sleep"
|
||||
.L36: .string "cmd_source"
|
||||
.L37: .string "cmd_test"
|
||||
.L38: .string "cmd_time"
|
||||
.L39: .string "cmd_truncate"
|
||||
.L40: .string "cmd_umount"
|
||||
.L41: .string "cmd_unalias"
|
||||
.L42: .string "cmd_uname"
|
||||
.L43: .string "cmd_unset"
|
||||
.L44: .string "cmd_uptime"
|
||||
.L45: .string "cmd_usleep"
|
||||
.L46: .string "cmd_xd"
|
||||
.L47: .string "cmsg_append"
|
||||
.L48: .string "dir_allocate"
|
||||
.L49: .string "exec_builtin"
|
||||
.L50: .string "icmp_alloc"
|
||||
.L51: .string "icmp_chksum_iob"
|
||||
.L52: .string "icmp_findconn"
|
||||
.L53: .string "icmp_free"
|
||||
.L54: .string "icmp_input"
|
||||
.L55: .string "icmp_ioctl"
|
||||
.L56: .string "icmp_nextconn"
|
||||
.L57: .string "icmp_poll"
|
||||
.L58: .string "icmp_pollsetup"
|
||||
.L59: .string "icmp_pollteardown"
|
||||
.L60: .string "icmp_recvmsg"
|
||||
.L61: .string "icmp_reply"
|
||||
.L62: .string "icmp_sendmsg"
|
||||
.L63: .string "icmpv6_advertise"
|
||||
.L64: .string "icmpv6_alloc"
|
||||
.L65: .string "icmpv6_autoconfig"
|
||||
.L66: .string "icmpv6_chksum"
|
||||
.L67: .string "icmpv6_foreach"
|
||||
.L68: .string "icmpv6_free"
|
||||
.L69: .string "icmpv6_input"
|
||||
.L70: .string "icmpv6_ioctl"
|
||||
.L71: .string "icmpv6_linkipaddr"
|
||||
.L72: .string "icmpv6_neighbor"
|
||||
.L73: .string "icmpv6_nextconn"
|
||||
.L74: .string "icmpv6_notify"
|
||||
.L75: .string "icmpv6_poll"
|
||||
.L76: .string "icmpv6_pollsetup"
|
||||
.L77: .string "icmpv6_pollteardown"
|
||||
.L78: .string "icmpv6_radvertise"
|
||||
.L79: .string "icmpv6_recvmsg"
|
||||
.L80: .string "icmpv6_reply"
|
||||
.L81: .string "icmpv6_rnotify"
|
||||
.L82: .string "icmpv6_rsolicit"
|
||||
.L83: .string "icmpv6_rwait"
|
||||
.L84: .string "icmpv6_rwait_cancel"
|
||||
.L85: .string "icmpv6_rwait_setup"
|
||||
.L86: .string "icmpv6_sendmsg"
|
||||
.L87: .string "icmpv6_setaddresses"
|
||||
.L88: .string "icmpv6_solicit"
|
||||
.L89: .string "icmpv6_wait"
|
||||
.L90: .string "icmpv6_wait_cancel"
|
||||
.L91: .string "icmpv6_wait_setup"
|
||||
.L92: .string "inet_close"
|
||||
.L93: .string "insmod"
|
||||
.L94: .string "ipv4_build_header"
|
||||
.L95: .string "ipv4_chksum"
|
||||
.L96: .string "ipv4_getpeername"
|
||||
.L97: .string "ipv4_getsockname"
|
||||
.L98: .string "ipv4_getsockopt"
|
||||
.L99: .string "ipv4_input"
|
||||
.L100: .string "ipv4_setsockopt"
|
||||
.L101: .string "ipv4_upperlayer_chksum"
|
||||
.L102: .string "ipv6_build_header"
|
||||
.L103: .string "ipv6_getpeername"
|
||||
.L104: .string "ipv6_getsockname"
|
||||
.L105: .string "ipv6_getsockopt"
|
||||
.L106: .string "ipv6_input"
|
||||
.L107: .string "ipv6_setsockopt"
|
||||
.L108: .string "ipv6_upperlayer_chksum"
|
||||
.L109: .string "kill"
|
||||
.L110: .string "kthread_create"
|
||||
.L111: .string "loop_register"
|
||||
.L112: .string "losetup"
|
||||
.L113: .string "loteardown"
|
||||
.L114: .string "lstat"
|
||||
.L115: .string "mkrd"
|
||||
.L116: .string "modhandle"
|
||||
.L117: .string "modsym"
|
||||
.L118: .string "mount"
|
||||
.L119: .string "neighbor_add"
|
||||
.L120: .string "neighbor_ethernet_out"
|
||||
.L121: .string "neighbor_findentry"
|
||||
.L122: .string "neighbor_lookup"
|
||||
.L123: .string "neighbor_out"
|
||||
.L124: .string "netdown_notifier_signal"
|
||||
.L125: .string "oneshot_register"
|
||||
.L126: .string "open_blockdriver"
|
||||
.L127: .string "panic_notifier_call_chain"
|
||||
.L128: .string "poll_notify"
|
||||
.L129: .string "pthread_cancel"
|
||||
.L130: .string "pthread_completejoin"
|
||||
.L131: .string "pthread_createjoininfo"
|
||||
.L132: .string "pthread_destroyjoin"
|
||||
.L133: .string "pthread_detach"
|
||||
.L134: .string "pthread_findjoininfo"
|
||||
.L135: .string "pthread_mutex_inconsistent"
|
||||
.L136: .string "pthread_release"
|
||||
.L137: .string "pthread_sem_give"
|
||||
.L138: .string "pthread_setup_scheduler"
|
||||
.L139: .string "ramdisk_register"
|
||||
.L140: .string "reboot_notifier_call_chain"
|
||||
.L141: .string "recv"
|
||||
.L142: .string "recvmsg"
|
||||
.L143: .string "rmmod"
|
||||
.L144: .string "romfs_checkmount"
|
||||
.L145: .string "romfs_datastart"
|
||||
.L146: .string "romfs_filecacheread"
|
||||
.L147: .string "romfs_fileconfigure"
|
||||
.L148: .string "romfs_finddirentry"
|
||||
.L149: .string "romfs_freenode"
|
||||
.L150: .string "romfs_fsconfigure"
|
||||
.L151: .string "romfs_hwconfigure"
|
||||
.L152: .string "romfs_hwread"
|
||||
.L153: .string "romfs_img"
|
||||
.L154: .string "romfs_img_len"
|
||||
.L155: .string "romfs_parsedirentry"
|
||||
.L156: .string "romfs_parsefilename"
|
||||
.L157: .string "rtc_initialize"
|
||||
.L158: .string "sem_clockwait"
|
||||
.L159: .string "sem_destroy"
|
||||
.L160: .string "sem_post"
|
||||
.L161: .string "sem_timedwait"
|
||||
.L162: .string "sem_trywait"
|
||||
.L163: .string "sem_wait"
|
||||
.L164: .string "send"
|
||||
.L165: .string "setenv"
|
||||
.L166: .string "sh_main"
|
||||
.L167: .string "sigpending"
|
||||
.L168: .string "sigprocmask"
|
||||
.L169: .string "sigtimedwait"
|
||||
.L170: .string "sotest_main"
|
||||
.L171: .string "sync"
|
||||
.L172: .string "sysinfo"
|
||||
.L173: .string "tcpip_hdrsize"
|
||||
.L174: .string "tls_init_info"
|
||||
.L175: .string "unsetenv"
|
||||
.L176: .string "waitpid"
|
||||
.L177: .string "work_cancel"
|
||||
.L178: .string "work_notifier_signal"
|
||||
.L179: .string "work_queue"
|
||||
.L180: .string "work_start_highpri"
|
||||
.L181: .string "work_start_lowpri"
|
||||
.size globalNames, . - globalNames
|
||||
|
||||
.align 8
|
||||
.global nGlobals
|
||||
.type nGlobals, "object"
|
||||
nGlobals:
|
||||
.word 182
|
||||
.size nGlobals, . - nGlobals
|
||||
|
||||
.align 8
|
||||
.global globalTable
|
||||
.type globalTable, "object"
|
||||
globalTable:
|
||||
.weak accept4
|
||||
.weak clearenv
|
||||
.weak cmd_alias
|
||||
.weak cmd_arp
|
||||
.weak cmd_basename
|
||||
.weak cmd_break
|
||||
.weak cmd_cat
|
||||
.weak cmd_cd
|
||||
.weak cmd_cmp
|
||||
.weak cmd_cp
|
||||
.weak cmd_date
|
||||
.weak cmd_dd
|
||||
.weak cmd_dirname
|
||||
.weak cmd_dmesg
|
||||
.weak cmd_echo
|
||||
.weak cmd_exec
|
||||
.weak cmd_hexdump
|
||||
.weak cmd_insmod
|
||||
.weak cmd_kill
|
||||
.weak cmd_lbracket
|
||||
.weak cmd_losetup
|
||||
.weak cmd_ls
|
||||
.weak cmd_mkdir
|
||||
.weak cmd_mkfifo
|
||||
.weak cmd_mkrd
|
||||
.weak cmd_mount
|
||||
.weak cmd_mv
|
||||
.weak cmd_nslookup
|
||||
.weak cmd_poweroff
|
||||
.weak cmd_printf
|
||||
.weak cmd_pwd
|
||||
.weak cmd_rm
|
||||
.weak cmd_rmdir
|
||||
.weak cmd_rmmod
|
||||
.weak cmd_set
|
||||
.weak cmd_sleep
|
||||
.weak cmd_source
|
||||
.weak cmd_test
|
||||
.weak cmd_time
|
||||
.weak cmd_truncate
|
||||
.weak cmd_umount
|
||||
.weak cmd_unalias
|
||||
.weak cmd_uname
|
||||
.weak cmd_unset
|
||||
.weak cmd_uptime
|
||||
.weak cmd_usleep
|
||||
.weak cmd_xd
|
||||
.weak cmsg_append
|
||||
.weak dir_allocate
|
||||
.weak exec_builtin
|
||||
.weak icmp_alloc
|
||||
.weak icmp_chksum_iob
|
||||
.weak icmp_findconn
|
||||
.weak icmp_free
|
||||
.weak icmp_input
|
||||
.weak icmp_ioctl
|
||||
.weak icmp_nextconn
|
||||
.weak icmp_poll
|
||||
.weak icmp_pollsetup
|
||||
.weak icmp_pollteardown
|
||||
.weak icmp_recvmsg
|
||||
.weak icmp_reply
|
||||
.weak icmp_sendmsg
|
||||
.weak icmpv6_advertise
|
||||
.weak icmpv6_alloc
|
||||
.weak icmpv6_autoconfig
|
||||
.weak icmpv6_chksum
|
||||
.weak icmpv6_foreach
|
||||
.weak icmpv6_free
|
||||
.weak icmpv6_input
|
||||
.weak icmpv6_ioctl
|
||||
.weak icmpv6_linkipaddr
|
||||
.weak icmpv6_neighbor
|
||||
.weak icmpv6_nextconn
|
||||
.weak icmpv6_notify
|
||||
.weak icmpv6_poll
|
||||
.weak icmpv6_pollsetup
|
||||
.weak icmpv6_pollteardown
|
||||
.weak icmpv6_radvertise
|
||||
.weak icmpv6_recvmsg
|
||||
.weak icmpv6_reply
|
||||
.weak icmpv6_rnotify
|
||||
.weak icmpv6_rsolicit
|
||||
.weak icmpv6_rwait
|
||||
.weak icmpv6_rwait_cancel
|
||||
.weak icmpv6_rwait_setup
|
||||
.weak icmpv6_sendmsg
|
||||
.weak icmpv6_setaddresses
|
||||
.weak icmpv6_solicit
|
||||
.weak icmpv6_wait
|
||||
.weak icmpv6_wait_cancel
|
||||
.weak icmpv6_wait_setup
|
||||
.weak inet_close
|
||||
.weak insmod
|
||||
.weak ipv4_build_header
|
||||
.weak ipv4_chksum
|
||||
.weak ipv4_getpeername
|
||||
.weak ipv4_getsockname
|
||||
.weak ipv4_getsockopt
|
||||
.weak ipv4_input
|
||||
.weak ipv4_setsockopt
|
||||
.weak ipv4_upperlayer_chksum
|
||||
.weak ipv6_build_header
|
||||
.weak ipv6_getpeername
|
||||
.weak ipv6_getsockname
|
||||
.weak ipv6_getsockopt
|
||||
.weak ipv6_input
|
||||
.weak ipv6_setsockopt
|
||||
.weak ipv6_upperlayer_chksum
|
||||
.weak kill
|
||||
.weak kthread_create
|
||||
.weak loop_register
|
||||
.weak losetup
|
||||
.weak loteardown
|
||||
.weak lstat
|
||||
.weak mkrd
|
||||
.weak modhandle
|
||||
.weak modsym
|
||||
.weak mount
|
||||
.weak neighbor_add
|
||||
.weak neighbor_ethernet_out
|
||||
.weak neighbor_findentry
|
||||
.weak neighbor_lookup
|
||||
.weak neighbor_out
|
||||
.weak netdown_notifier_signal
|
||||
.weak oneshot_register
|
||||
.weak open_blockdriver
|
||||
.weak panic_notifier_call_chain
|
||||
.weak poll_notify
|
||||
.weak pthread_cancel
|
||||
.weak pthread_completejoin
|
||||
.weak pthread_createjoininfo
|
||||
.weak pthread_destroyjoin
|
||||
.weak pthread_detach
|
||||
.weak pthread_findjoininfo
|
||||
.weak pthread_mutex_inconsistent
|
||||
.weak pthread_release
|
||||
.weak pthread_sem_give
|
||||
.weak pthread_setup_scheduler
|
||||
.weak ramdisk_register
|
||||
.weak reboot_notifier_call_chain
|
||||
.weak recv
|
||||
.weak recvmsg
|
||||
.weak rmmod
|
||||
.weak romfs_checkmount
|
||||
.weak romfs_datastart
|
||||
.weak romfs_filecacheread
|
||||
.weak romfs_fileconfigure
|
||||
.weak romfs_finddirentry
|
||||
.weak romfs_freenode
|
||||
.weak romfs_fsconfigure
|
||||
.weak romfs_hwconfigure
|
||||
.weak romfs_hwread
|
||||
.weak romfs_img
|
||||
.weak romfs_img_len
|
||||
.weak romfs_parsedirentry
|
||||
.weak romfs_parsefilename
|
||||
.weak rtc_initialize
|
||||
.weak sem_clockwait
|
||||
.weak sem_destroy
|
||||
.weak sem_post
|
||||
.weak sem_timedwait
|
||||
.weak sem_trywait
|
||||
.weak sem_wait
|
||||
.weak send
|
||||
.weak setenv
|
||||
.weak sh_main
|
||||
.weak sigpending
|
||||
.weak sigprocmask
|
||||
.weak sigtimedwait
|
||||
.weak sotest_main
|
||||
.weak sync
|
||||
.weak sysinfo
|
||||
.weak tcpip_hdrsize
|
||||
.weak tls_init_info
|
||||
.weak unsetenv
|
||||
.weak waitpid
|
||||
.weak work_cancel
|
||||
.weak work_notifier_signal
|
||||
.weak work_queue
|
||||
.weak work_start_highpri
|
||||
.weak work_start_lowpri
|
||||
.quad .L0, accept4
|
||||
.quad .L1, clearenv
|
||||
.quad .L2, cmd_alias
|
||||
.quad .L3, cmd_arp
|
||||
.quad .L4, cmd_basename
|
||||
.quad .L5, cmd_break
|
||||
.quad .L6, cmd_cat
|
||||
.quad .L7, cmd_cd
|
||||
.quad .L8, cmd_cmp
|
||||
.quad .L9, cmd_cp
|
||||
.quad .L10, cmd_date
|
||||
.quad .L11, cmd_dd
|
||||
.quad .L12, cmd_dirname
|
||||
.quad .L13, cmd_dmesg
|
||||
.quad .L14, cmd_echo
|
||||
.quad .L15, cmd_exec
|
||||
.quad .L16, cmd_hexdump
|
||||
.quad .L17, cmd_insmod
|
||||
.quad .L18, cmd_kill
|
||||
.quad .L19, cmd_lbracket
|
||||
.quad .L20, cmd_losetup
|
||||
.quad .L21, cmd_ls
|
||||
.quad .L22, cmd_mkdir
|
||||
.quad .L23, cmd_mkfifo
|
||||
.quad .L24, cmd_mkrd
|
||||
.quad .L25, cmd_mount
|
||||
.quad .L26, cmd_mv
|
||||
.quad .L27, cmd_nslookup
|
||||
.quad .L28, cmd_poweroff
|
||||
.quad .L29, cmd_printf
|
||||
.quad .L30, cmd_pwd
|
||||
.quad .L31, cmd_rm
|
||||
.quad .L32, cmd_rmdir
|
||||
.quad .L33, cmd_rmmod
|
||||
.quad .L34, cmd_set
|
||||
.quad .L35, cmd_sleep
|
||||
.quad .L36, cmd_source
|
||||
.quad .L37, cmd_test
|
||||
.quad .L38, cmd_time
|
||||
.quad .L39, cmd_truncate
|
||||
.quad .L40, cmd_umount
|
||||
.quad .L41, cmd_unalias
|
||||
.quad .L42, cmd_uname
|
||||
.quad .L43, cmd_unset
|
||||
.quad .L44, cmd_uptime
|
||||
.quad .L45, cmd_usleep
|
||||
.quad .L46, cmd_xd
|
||||
.quad .L47, cmsg_append
|
||||
.quad .L48, dir_allocate
|
||||
.quad .L49, exec_builtin
|
||||
.quad .L50, icmp_alloc
|
||||
.quad .L51, icmp_chksum_iob
|
||||
.quad .L52, icmp_findconn
|
||||
.quad .L53, icmp_free
|
||||
.quad .L54, icmp_input
|
||||
.quad .L55, icmp_ioctl
|
||||
.quad .L56, icmp_nextconn
|
||||
.quad .L57, icmp_poll
|
||||
.quad .L58, icmp_pollsetup
|
||||
.quad .L59, icmp_pollteardown
|
||||
.quad .L60, icmp_recvmsg
|
||||
.quad .L61, icmp_reply
|
||||
.quad .L62, icmp_sendmsg
|
||||
.quad .L63, icmpv6_advertise
|
||||
.quad .L64, icmpv6_alloc
|
||||
.quad .L65, icmpv6_autoconfig
|
||||
.quad .L66, icmpv6_chksum
|
||||
.quad .L67, icmpv6_foreach
|
||||
.quad .L68, icmpv6_free
|
||||
.quad .L69, icmpv6_input
|
||||
.quad .L70, icmpv6_ioctl
|
||||
.quad .L71, icmpv6_linkipaddr
|
||||
.quad .L72, icmpv6_neighbor
|
||||
.quad .L73, icmpv6_nextconn
|
||||
.quad .L74, icmpv6_notify
|
||||
.quad .L75, icmpv6_poll
|
||||
.quad .L76, icmpv6_pollsetup
|
||||
.quad .L77, icmpv6_pollteardown
|
||||
.quad .L78, icmpv6_radvertise
|
||||
.quad .L79, icmpv6_recvmsg
|
||||
.quad .L80, icmpv6_reply
|
||||
.quad .L81, icmpv6_rnotify
|
||||
.quad .L82, icmpv6_rsolicit
|
||||
.quad .L83, icmpv6_rwait
|
||||
.quad .L84, icmpv6_rwait_cancel
|
||||
.quad .L85, icmpv6_rwait_setup
|
||||
.quad .L86, icmpv6_sendmsg
|
||||
.quad .L87, icmpv6_setaddresses
|
||||
.quad .L88, icmpv6_solicit
|
||||
.quad .L89, icmpv6_wait
|
||||
.quad .L90, icmpv6_wait_cancel
|
||||
.quad .L91, icmpv6_wait_setup
|
||||
.quad .L92, inet_close
|
||||
.quad .L93, insmod
|
||||
.quad .L94, ipv4_build_header
|
||||
.quad .L95, ipv4_chksum
|
||||
.quad .L96, ipv4_getpeername
|
||||
.quad .L97, ipv4_getsockname
|
||||
.quad .L98, ipv4_getsockopt
|
||||
.quad .L99, ipv4_input
|
||||
.quad .L100, ipv4_setsockopt
|
||||
.quad .L101, ipv4_upperlayer_chksum
|
||||
.quad .L102, ipv6_build_header
|
||||
.quad .L103, ipv6_getpeername
|
||||
.quad .L104, ipv6_getsockname
|
||||
.quad .L105, ipv6_getsockopt
|
||||
.quad .L106, ipv6_input
|
||||
.quad .L107, ipv6_setsockopt
|
||||
.quad .L108, ipv6_upperlayer_chksum
|
||||
.quad .L109, kill
|
||||
.quad .L110, kthread_create
|
||||
.quad .L111, loop_register
|
||||
.quad .L112, losetup
|
||||
.quad .L113, loteardown
|
||||
.quad .L114, lstat
|
||||
.quad .L115, mkrd
|
||||
.quad .L116, modhandle
|
||||
.quad .L117, modsym
|
||||
.quad .L118, mount
|
||||
.quad .L119, neighbor_add
|
||||
.quad .L120, neighbor_ethernet_out
|
||||
.quad .L121, neighbor_findentry
|
||||
.quad .L122, neighbor_lookup
|
||||
.quad .L123, neighbor_out
|
||||
.quad .L124, netdown_notifier_signal
|
||||
.quad .L125, oneshot_register
|
||||
.quad .L126, open_blockdriver
|
||||
.quad .L127, panic_notifier_call_chain
|
||||
.quad .L128, poll_notify
|
||||
.quad .L129, pthread_cancel
|
||||
.quad .L130, pthread_completejoin
|
||||
.quad .L131, pthread_createjoininfo
|
||||
.quad .L132, pthread_destroyjoin
|
||||
.quad .L133, pthread_detach
|
||||
.quad .L134, pthread_findjoininfo
|
||||
.quad .L135, pthread_mutex_inconsistent
|
||||
.quad .L136, pthread_release
|
||||
.quad .L137, pthread_sem_give
|
||||
.quad .L138, pthread_setup_scheduler
|
||||
.quad .L139, ramdisk_register
|
||||
.quad .L140, reboot_notifier_call_chain
|
||||
.quad .L141, recv
|
||||
.quad .L142, recvmsg
|
||||
.quad .L143, rmmod
|
||||
.quad .L144, romfs_checkmount
|
||||
.quad .L145, romfs_datastart
|
||||
.quad .L146, romfs_filecacheread
|
||||
.quad .L147, romfs_fileconfigure
|
||||
.quad .L148, romfs_finddirentry
|
||||
.quad .L149, romfs_freenode
|
||||
.quad .L150, romfs_fsconfigure
|
||||
.quad .L151, romfs_hwconfigure
|
||||
.quad .L152, romfs_hwread
|
||||
.quad .L153, romfs_img
|
||||
.quad .L154, romfs_img_len
|
||||
.quad .L155, romfs_parsedirentry
|
||||
.quad .L156, romfs_parsefilename
|
||||
.quad .L157, rtc_initialize
|
||||
.quad .L158, sem_clockwait
|
||||
.quad .L159, sem_destroy
|
||||
.quad .L160, sem_post
|
||||
.quad .L161, sem_timedwait
|
||||
.quad .L162, sem_trywait
|
||||
.quad .L163, sem_wait
|
||||
.quad .L164, send
|
||||
.quad .L165, setenv
|
||||
.quad .L166, sh_main
|
||||
.quad .L167, sigpending
|
||||
.quad .L168, sigprocmask
|
||||
.quad .L169, sigtimedwait
|
||||
.quad .L170, sotest_main
|
||||
.quad .L171, sync
|
||||
.quad .L172, sysinfo
|
||||
.quad .L173, tcpip_hdrsize
|
||||
.quad .L174, tls_init_info
|
||||
.quad .L175, unsetenv
|
||||
.quad .L176, waitpid
|
||||
.quad .L177, work_cancel
|
||||
.quad .L178, work_notifier_signal
|
||||
.quad .L179, work_queue
|
||||
.quad .L180, work_start_highpri
|
||||
.quad .L181, work_start_lowpri
|
||||
.size globalTable, . - globalTable
|
Loading…
Reference in a new issue