apps/examples: In elf and nxflat examples, remove low-level interfaces and replace with call to exec().

This commit is contained in:
Gregory Nutt 2017-10-02 14:32:17 -06:00
parent 661a593939
commit 56814bec38
4 changed files with 61 additions and 96 deletions

View File

@ -6,6 +6,7 @@
config EXAMPLES_ELF config EXAMPLES_ELF
bool "ELF Loader Example" bool "ELF Loader Example"
default n default n
select LIBC_EXECFUNCS
---help--- ---help---
Enable the ELF loader example Enable the ELF loader example

View File

@ -50,10 +50,9 @@
#include <debug.h> #include <debug.h>
#include <errno.h> #include <errno.h>
#include <nuttx/symtab.h>
#include <nuttx/drivers/ramdisk.h> #include <nuttx/drivers/ramdisk.h>
#include <nuttx/binfmt/binfmt.h> #include <nuttx/binfmt/binfmt.h>
#include <nuttx/binfmt/elf.h>
#include <nuttx/binfmt/symtab.h>
#include "platform/cxxinitialize.h" #include "platform/cxxinitialize.h"
@ -107,27 +106,29 @@
*/ */
#ifdef CONFIG_CPP_HAVE_VARARGS #ifdef CONFIG_CPP_HAVE_VARARGS
# ifdef CONFIG_DEBUG_FEATURES # ifdef CONFIG_DEBUG_INFO
# define message(format, ...) _info(format, ##__VA_ARGS__) # define message(format, ...) syslog(LOG_INFO, format, ##__VA_ARGS__)
# define errmsg(format, ...) _err(format, ##__VA_ARGS__)
# else # else
# define message(format, ...) printf(format, ##__VA_ARGS__) # define message(format, ...) printf(format, ##__VA_ARGS__)
# endif
# ifdef CONFIG_DEBUG_ERROR
# define errmsg(format, ...) syslog(LOG_ERR, format, ##__VA_ARGS__)
# else
# define errmsg(format, ...) fprintf(stderr, format, ##__VA_ARGS__) # define errmsg(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
# endif # endif
#else #else
# ifdef CONFIG_DEBUG_FEATURES # ifdef CONFIG_DEBUG_INFO
# define message _info # define message _info
# define errmsg _err
# else # else
# define message printf # define message printf
# endif
# ifdef CONFIG_DEBUG_ERROR
# define errmsg _err
# else
# define errmsg printf # define errmsg printf
# endif # endif
#endif #endif
/****************************************************************************
* Private Types
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
@ -223,13 +224,13 @@ int main(int argc, FAR char *argv[])
int elf_main(int argc, char *argv[]) int elf_main(int argc, char *argv[])
#endif #endif
{ {
struct binary_s bin; FAR char *args[1];
int ret; int ret;
int i; int i;
#if defined(CONFIG_EXAMPLES_ELF_CXXINITIALIZE)
/* Call all C++ static constructors */ /* Call all C++ static constructors */
#if defined(CONFIG_EXAMPLES_ELF_CXXINITIALIZE)
up_cxxinitialize(); up_cxxinitialize();
#endif #endif
@ -237,27 +238,16 @@ int elf_main(int argc, char *argv[])
mm_initmonitor(); mm_initmonitor();
/* Initialize the ELF binary loader */
message("Initializing the ELF binary loader\n");
ret = elf_initialize();
if (ret < 0)
{
errmsg("ERROR: Initialization of the ELF loader failed: %d\n", ret);
exit(1);
}
mm_update(&g_mmstep, "after elf_initialize");
/* Create a ROM disk for the ROMFS filesystem */ /* Create a ROM disk for the ROMFS filesystem */
message("Registering romdisk at /dev/ram%d\n", CONFIG_EXAMPLES_ELF_DEVMINOR); message("Registering romdisk at /dev/ram%d\n",
ret = romdisk_register(CONFIG_EXAMPLES_ELF_DEVMINOR, (FAR uint8_t *)romfs_img, CONFIG_EXAMPLES_ELF_DEVMINOR);
ret = romdisk_register(CONFIG_EXAMPLES_ELF_DEVMINOR,
(FAR uint8_t *)romfs_img,
NSECTORS(romfs_img_len), SECTORSIZE); NSECTORS(romfs_img_len), SECTORSIZE);
if (ret < 0) if (ret < 0)
{ {
errmsg("ERROR: romdisk_register failed: %d\n", ret); errmsg("ERROR: romdisk_register failed: %d\n", ret);
elf_uninitialize();
exit(1); exit(1);
} }
@ -273,17 +263,16 @@ int elf_main(int argc, char *argv[])
{ {
errmsg("ERROR: mount(%s,%s,romfs) failed: %s\n", errmsg("ERROR: mount(%s,%s,romfs) failed: %s\n",
CONFIG_EXAMPLES_ELF_DEVPATH, MOUNTPT, errno); CONFIG_EXAMPLES_ELF_DEVPATH, MOUNTPT, errno);
elf_uninitialize();
} }
mm_update(&g_mmstep, "after mount"); mm_update(&g_mmstep, "after mount");
#if defined(CONFIG_BINFMT_EXEPATH) && !defined(CONFIG_PATH_INITIAL)
/* Does the system support the PATH variable? Has the PATH variable /* Does the system support the PATH variable? Has the PATH variable
* already been set? If YES and NO, then set the PATH variable to * already been set? If YES and NO, then set the PATH variable to
* the ROMFS mountpoint. * the ROMFS mountpoint.
*/ */
#if defined(CONFIG_BINFMT_EXEPATH) && !defined(CONFIG_PATH_INITIAL)
(void)setenv("PATH", MOUNTPT, 1); (void)setenv("PATH", MOUNTPT, 1);
#endif #endif
@ -291,16 +280,14 @@ int elf_main(int argc, char *argv[])
for (i = 0; dirlist[i]; i++) for (i = 0; dirlist[i]; i++)
{ {
FAR const char *filename;
/* Output a seperated so that we can clearly discrinmate the output of /* Output a seperated so that we can clearly discrinmate the output of
* this program from the others. * this program from the others.
*/ */
testheader(dirlist[i]); testheader(dirlist[i]);
/* Initialize the binary_s structure */
memset(&bin, 0, sizeof(struct binary_s));
/* If the binary loader does not support the PATH variable, then /* If the binary loader does not support the PATH variable, then
* create the full path to the executable program. Otherwise, * create the full path to the executable program. Otherwise,
* use the relative path so that the binary loader will have to * use the relative path so that the binary loader will have to
@ -308,34 +295,22 @@ int elf_main(int argc, char *argv[])
*/ */
#ifdef CONFIG_BINFMT_EXEPATH #ifdef CONFIG_BINFMT_EXEPATH
bin.filename = dirlist[i]; filename = dirlist[i];
#else #else
snprintf(fullpath, 128, "%s/%s", MOUNTPT, dirlist[i]); snprintf(fullpath, 128, "%s/%s", MOUNTPT, dirlist[i]);
bin.filename = fullpath; filename = fullpath;
#endif #endif
bin.exports = exports;
bin.nexports = nexports;
/* Load the ELF module */
ret = load_module(&bin);
if (ret < 0)
{
errmsg("ERROR: Failed to load program '%s'\n", dirlist[i]);
exit(1);
}
mm_update(&g_mmstep, "after load_module");
/* Execute the ELF module */ /* Execute the ELF module */
ret = exec_module(&bin); args[0] = NULL;
ret = exec(filename, args, exports, nexports);
mm_update(&g_mmstep, "after exec_module"); mm_update(&g_mmstep, "after exec");
if (ret < 0) if (ret < 0)
{ {
errmsg("ERROR: Failed to execute program '%s'\n", dirlist[i]); errmsg("ERROR: exec(%s) failed: %d\n", dirlist[i], errno);
} }
else else
{ {
@ -343,8 +318,7 @@ int elf_main(int argc, char *argv[])
sleep(4); sleep(4);
} }
unload_module(&bin); mm_update(&g_mmstep, "after program execution");
mm_update(&g_mmstep, "after unload_module");
} }
mm_update(&g_mmstep, "End-of-Test"); mm_update(&g_mmstep, "End-of-Test");

View File

@ -6,6 +6,7 @@
config EXAMPLES_NXFLAT config EXAMPLES_NXFLAT
bool "NXFLAT example" bool "NXFLAT example"
default n default n
select LIBC_EXECFUNCS
depends on NXFLAT && BUILD_FLAT depends on NXFLAT && BUILD_FLAT
---help--- ---help---
Enable the NXFLAT example Enable the NXFLAT example

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* examples/nxflat/nxflat_main.c * examples/nxflat/nxflat_main.c
* *
* Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2009, 2011, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -49,9 +49,9 @@
#include <debug.h> #include <debug.h>
#include <errno.h> #include <errno.h>
#include <nuttx/symtab.h>
#include <nuttx/drivers/ramdisk.h> #include <nuttx/drivers/ramdisk.h>
#include <nuttx/binfmt/binfmt.h> #include <nuttx/binfmt/binfmt.h>
#include <nuttx/binfmt/nxflat.h>
#include "tests/romfs.h" #include "tests/romfs.h"
#include "tests/dirlist.h" #include "tests/dirlist.h"
@ -96,32 +96,34 @@
#define ROMFSDEV "/dev/ram0" #define ROMFSDEV "/dev/ram0"
#define MOUNTPT "/mnt/romfs" #define MOUNTPT "/mnt/romfs"
/* If CONFIG_DEBUG_FEATURES is enabled, use info/err instead of printf so that the /* If CONFIG_DEBUG_FEATURES is enabled, use info/err instead of printf so
* output will be synchronous with the debug output. * that the output will be synchronous with the debug output.
*/ */
#ifdef CONFIG_CPP_HAVE_VARARGS #ifdef CONFIG_CPP_HAVE_VARARGS
# ifdef CONFIG_DEBUG_FEATURES # ifdef CONFIG_DEBUG_INFO
# define message(format, ...) _info(format, ##__VA_ARGS__) # define message(format, ...) syslog(LOG_INFO, format, ##__VA_ARGS__)
# define errmsg(format, ...) _err(format, ##__VA_ARGS__)
# else # else
# define message(format, ...) printf(format, ##__VA_ARGS__) # define message(format, ...) printf(format, ##__VA_ARGS__)
# endif
# ifdef CONFIG_DEBUG_ERROR
# define errmsg(format, ...) syslog(LOG_ERR, format, ##__VA_ARGS__)
# else
# define errmsg(format, ...) fprintf(stderr, format, ##__VA_ARGS__) # define errmsg(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
# endif # endif
#else #else
# ifdef CONFIG_DEBUG_FEATURES # ifdef CONFIG_DEBUG_INFO
# define message _info # define message _info
# define errmsg _err
# else # else
# define message printf # define message printf
# endif
# ifdef CONFIG_DEBUG_ERROR
# define errmsg _err
# else
# define errmsg printf # define errmsg printf
# endif # endif
#endif #endif
/****************************************************************************
* Private Types
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
@ -160,28 +162,18 @@ int main(int argc, FAR char *argv[])
int nxflat_main(int argc, char *argv[]) int nxflat_main(int argc, char *argv[])
#endif #endif
{ {
struct binary_s bin; FAR char *args[1];
int ret; int ret;
int i; int i;
/* Initialize the NXFLAT binary loader */
message("Initializing the NXFLAT binary loader\n");
ret = nxflat_initialize();
if (ret < 0)
{
errmsg("ERROR: Initialization of the NXFLAT loader failed: %d\n", ret);
exit(1);
}
/* Create a ROM disk for the ROMFS filesystem */ /* Create a ROM disk for the ROMFS filesystem */
message("Registering romdisk\n"); message("Registering romdisk\n");
ret = romdisk_register(0, (FAR uint8_t *)romfs_img, NSECTORS(romfs_img_len), SECTORSIZE); ret = romdisk_register(0, (FAR uint8_t *)romfs_img,
NSECTORS(romfs_img_len), SECTORSIZE);
if (ret < 0) if (ret < 0)
{ {
errmsg("ERROR: romdisk_register failed: %d\n", ret); errmsg("ERROR: romdisk_register failed: %d\n", ret);
nxflat_uninitialize();
exit(1); exit(1);
} }
@ -195,15 +187,14 @@ int nxflat_main(int argc, char *argv[])
{ {
errmsg("ERROR: mount(%s,%s,romfs) failed: %s\n", errmsg("ERROR: mount(%s,%s,romfs) failed: %s\n",
ROMFSDEV, MOUNTPT, errno); ROMFSDEV, MOUNTPT, errno);
nxflat_uninitialize();
} }
#if defined(CONFIG_BINFMT_EXEPATH) && !defined(CONFIG_PATH_INITIAL)
/* Does the system support the PATH variable? Has the PATH variable /* Does the system support the PATH variable? Has the PATH variable
* already been set? If YES and NO, then set the PATH variable to * already been set? If YES and NO, then set the PATH variable to
* the ROMFS mountpoint. * the ROMFS mountpoint.
*/ */
#if defined(CONFIG_BINFMT_EXEPATH) && !defined(CONFIG_PATH_INITIAL)
(void)setenv("PATH", MOUNTPT, 1); (void)setenv("PATH", MOUNTPT, 1);
#endif #endif
@ -211,16 +202,14 @@ int nxflat_main(int argc, char *argv[])
for (i = 0; dirlist[i]; i++) for (i = 0; dirlist[i]; i++)
{ {
FAR const char *filename;
/* Output a seperated so that we can clearly discrinmate the output of /* Output a seperated so that we can clearly discrinmate the output of
* this program from the others. * this program from the others.
*/ */
testheader(dirlist[i]); testheader(dirlist[i]);
/* Initialize the binary_s structure */
memset(&bin, 0, sizeof(struct binary_s));
/* If the binary loader does not support the PATH variable, then /* If the binary loader does not support the PATH variable, then
* create the full path to the executable program. Otherwise, * create the full path to the executable program. Otherwise,
* use the relative path so that the binary loader will have to * use the relative path so that the binary loader will have to
@ -228,17 +217,16 @@ int nxflat_main(int argc, char *argv[])
*/ */
#ifdef CONFIG_BINFMT_EXEPATH #ifdef CONFIG_BINFMT_EXEPATH
bin.filename = dirlist[i]; filename = dirlist[i];
#else #else
snprintf(fullpath, 128, "%s/%s", MOUNTPT, dirlist[i]); snprintf(fullpath, 128, "%s/%s", MOUNTPT, dirlist[i]);
bin.filename = fullpath; filename = fullpath;
#endif #endif
bin.exports = exports;
bin.nexports = NEXPORTS;
/* Load the NXFLAT module */ /* Load the NXFLAT module */
ret = load_module(&bin); args[0] = NULL;
ret = exec(filename, args, exports, NEXPORTS);
if (ret < 0) if (ret < 0)
{ {
errmsg("ERROR: Failed to load program '%s'\n", dirlist[i]); errmsg("ERROR: Failed to load program '%s'\n", dirlist[i]);
@ -250,12 +238,13 @@ int nxflat_main(int argc, char *argv[])
ret = exec_module(&bin); ret = exec_module(&bin);
if (ret < 0) if (ret < 0)
{ {
errmsg("ERROR: Failed to execute program '%s'\n", dirlist[i]); errmsg("ERROR: exec(%s) failed: %d\n", dirlist[i], errno);
unload_module(&bin); }
else
{
message("Wait a bit for test completion\n");
sleep(4);
} }
message("Wait a bit for test completion\n");
sleep(4);
} }
message("End-of-Test.. Exit-ing\n"); message("End-of-Test.. Exit-ing\n");