The ELF loader is basically functional (needs more testing)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5265 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
f863b72ced
commit
603f1f0317
@ -383,4 +383,5 @@
|
||||
* apps/Makefile: Small change that reduces the number of shell invocations
|
||||
by one (Mike Smith).
|
||||
* apps/examples/elf: Test example for the ELF loader.
|
||||
* apps/examples/elf: The ELF module test example appears fully functional.
|
||||
|
||||
|
@ -318,7 +318,12 @@ examples/elf
|
||||
|
||||
NOTES:
|
||||
|
||||
1. Your top-level nuttx/Make.defs file must include an approproate definition,
|
||||
1. CFLAGS should be provided in CELFFLAGS. RAM and FLASH memory regions
|
||||
may require long allcs. For ARM, this might be:
|
||||
|
||||
CELFFLAGS = $(CFLAGS) -mlong-calls
|
||||
|
||||
2. Your top-level nuttx/Make.defs file must alos include an approproate definition,
|
||||
LDELFFLAGS, to generate a relocatable ELF object. With GNU LD, this should
|
||||
include '-r' and '-e main' (or _main on some platforms).
|
||||
|
||||
@ -327,24 +332,24 @@ examples/elf
|
||||
If you use GCC to link, you make also need to include '-nostdlib' or
|
||||
'-nostartfiles' and '-nodefaultlibs'.
|
||||
|
||||
2. This example also requires genromfs. genromfs can be build as part of the
|
||||
3. This example also requires genromfs. genromfs can be build as part of the
|
||||
nuttx toolchain. Or can built from the genromfs sources that can be found
|
||||
at misc/tools/genromfs-0.5.2.tar.gz. In any event, the PATH variable must
|
||||
include the path to the genromfs executable.
|
||||
|
||||
3. ELF size: The ELF files in this example are, be default, quite large
|
||||
4. ELF size: The ELF files in this example are, be default, quite large
|
||||
because they include a lot of "build garbage". You can greatly reduce the
|
||||
size of the ELF binaries are using the 'objcopy --strip-unneeded' command to
|
||||
remove un-necessary information from the ELF files.
|
||||
|
||||
4. Simulator. You cannot use this example with the the NuttX simulator on
|
||||
5. Simulator. You cannot use this example with the the NuttX simulator on
|
||||
Cygwin. That is because the Cygwin GCC does not generate ELF file but
|
||||
rather some Windows-native binary format.
|
||||
|
||||
If you really want to do this, you can create a NuttX x86 buildroot toolchain
|
||||
and use that be build the ELF executables for the ROMFS file system.
|
||||
|
||||
5. Linker scripts. You might also want to use a linker scripts to combine
|
||||
6. Linker scripts. You might also want to use a linker scripts to combine
|
||||
sections better. An example linker script is at nuttx/binfmt/libelf/gnu-elf.ld.
|
||||
That example might have to be tuned for your particular linker output to
|
||||
position additional sections correctly. The GNU LD LDELFFLAGS then might
|
||||
|
@ -39,29 +39,29 @@ include $(APPDIR)/Make.defs
|
||||
|
||||
# ELF Example
|
||||
|
||||
ASRCS =
|
||||
CSRCS = elf_main.c
|
||||
ASRCS =
|
||||
CSRCS = elf_main.c symtab.c
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
ifeq ($(WINTOOL),y)
|
||||
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
|
||||
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
|
||||
else
|
||||
BIN = "$(APPDIR)/libapps$(LIBEXT)"
|
||||
BIN = "$(APPDIR)/libapps$(LIBEXT)"
|
||||
endif
|
||||
|
||||
ROOTDEPPATH = --dep-path .
|
||||
ROOTDEPPATH = --dep-path . --dep-path tests
|
||||
|
||||
# Common build
|
||||
# Build targets
|
||||
|
||||
VPATH =
|
||||
VPATH = tests
|
||||
|
||||
all: .built
|
||||
.PHONY: headers clean_tests clean depend disclean
|
||||
.PHONY: really_build clean_tests clean depend disclean
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(call ASSEMBLE, $<, $@)
|
||||
@ -69,15 +69,21 @@ $(AOBJS): %$(OBJEXT): %.S
|
||||
$(COBJS): %$(OBJEXT): %.c
|
||||
$(call COMPILE, $<, $@)
|
||||
|
||||
headers:
|
||||
@$(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
|
||||
# This is a little messy. The build is broken into two pieces: (1) the
|
||||
# tests/ subdir build that auto-generates several files, and (2) the real
|
||||
# build. This is done because we need a fresh build context after auto-
|
||||
# generating the source files.
|
||||
|
||||
.built: headers $(OBJS)
|
||||
really_build: $(OBJS)
|
||||
@( for obj in $(OBJS) ; do \
|
||||
$(call ARCHIVE, $(BIN), $${obj}); \
|
||||
done ; )
|
||||
@touch .built
|
||||
|
||||
.built:
|
||||
@$(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
|
||||
@$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" really_build
|
||||
|
||||
context:
|
||||
|
||||
# We can't make dependencies in this directory because the required
|
||||
|
@ -52,10 +52,10 @@
|
||||
#include <nuttx/ramdisk.h>
|
||||
#include <nuttx/binfmt/binfmt.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
#include <nuttx/binfmt/symtab.h>
|
||||
|
||||
#include "tests/romfs.h"
|
||||
#include "tests/dirlist.h"
|
||||
#include "tests/symtab.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
@ -134,6 +134,13 @@ static const char delimiter[] =
|
||||
|
||||
static char path[128];
|
||||
|
||||
/****************************************************************************
|
||||
* Symbols from Auto-Generated Code
|
||||
****************************************************************************/
|
||||
|
||||
extern const struct symtab_s exports[];
|
||||
extern const int nexports;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@ -207,7 +214,7 @@ int elf_main(int argc, char *argv[])
|
||||
|
||||
bin.filename = path;
|
||||
bin.exports = exports;
|
||||
bin.nexports = NEXPORTS;
|
||||
bin.nexports = nexports;
|
||||
|
||||
ret = load_module(&bin);
|
||||
if (ret < 0)
|
||||
|
@ -34,35 +34,53 @@
|
||||
############################################################################
|
||||
|
||||
# Most of these do no build yet
|
||||
SUBDIRS = errno hello hello++ longjmp mutex pthread signal task struct
|
||||
|
||||
ALL_SUBDIRS = errno hello hello++ longjmp mutex pthread signal task struct
|
||||
BUILD_SUBDIRS = errno hello task struct
|
||||
|
||||
ifeq ($(CONFIG_HAVE_CXX),y)
|
||||
BUILD_SUBDIRS += hello++
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_EXAMPLES_ELF_LONGJMP),y)
|
||||
BUILD_SUBDIRS += longjmp
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
||||
BUILD_SUBDIRS += mutex pthread
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||
BUILD_SUBDIRS += signal
|
||||
endif
|
||||
|
||||
ELF_DIR = $(APPDIR)/examples/elf
|
||||
TESTS_DIR = $(ELF_DIR)/tests
|
||||
ROMFS_DIR = $(TESTS_DIR)/romfs
|
||||
ROMFS_IMG = $(TESTS_DIR)/romfs.img
|
||||
ROMFS_HDR = $(TESTS_DIR)/romfs.h
|
||||
ROMFS_DIRLIST = $(TESTS_DIR)/dirlist.h
|
||||
SYMTAB = $(TESTS_DIR)/symtab.h
|
||||
DIRLIST_HDR = $(TESTS_DIR)/dirlist.h
|
||||
SYMTAB_SRC = $(TESTS_DIR)/symtab.c
|
||||
|
||||
define DIR_template
|
||||
$(1)_$(2):
|
||||
@$(MAKE) -C $(1) $(3) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" CROSSDEV=$(CROSSDEV)
|
||||
endef
|
||||
|
||||
all: $(ROMFS_HDR) $(ROMFS_DIRLIST) $(SYMTAB)
|
||||
all: $(ROMFS_HDR) $(DIRLIST_HDR) $(SYMTAB_SRC)
|
||||
.PHONY: all build clean install populate
|
||||
|
||||
$(foreach DIR, $(SUBDIRS), $(eval $(call DIR_template,$(DIR),build, all)))
|
||||
$(foreach DIR, $(SUBDIRS), $(eval $(call DIR_template,$(DIR),clean,clean)))
|
||||
$(foreach DIR, $(SUBDIRS), $(eval $(call DIR_template,$(DIR),install,install)))
|
||||
$(foreach DIR, $(BUILD_SUBDIRS), $(eval $(call DIR_template,$(DIR),build, all)))
|
||||
$(foreach DIR, $(ALL_SUBDIRS), $(eval $(call DIR_template,$(DIR),clean,clean)))
|
||||
$(foreach DIR, $(BUILD_SUBDIRS), $(eval $(call DIR_template,$(DIR),install,install)))
|
||||
|
||||
# Build program(s) in each sud-directory
|
||||
|
||||
build: $(foreach DIR, $(SUBDIRS), $(DIR)_build)
|
||||
build: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_build)
|
||||
|
||||
# Install each program in the romfs directory
|
||||
|
||||
install: $(foreach DIR, $(SUBDIRS), $(DIR)_install)
|
||||
install: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_install)
|
||||
|
||||
# Create the romfs directory
|
||||
|
||||
@ -85,16 +103,16 @@ $(ROMFS_HDR) : $(ROMFS_IMG)
|
||||
|
||||
# Create the dirlist.h header file from the romfs directory
|
||||
|
||||
$(ROMFS_DIRLIST) : populate
|
||||
$(DIRLIST_HDR) : populate
|
||||
@$(TESTS_DIR)/mkdirlist.sh $(ROMFS_DIR) >$@
|
||||
|
||||
# Create the exported symbol table list from the derived *-thunk.S files
|
||||
|
||||
$(SYMTAB): build
|
||||
@$(TESTS_DIR)/mksymtab.sh $(TESTS_DIR) >$@
|
||||
$(SYMTAB_SRC): build
|
||||
@$(TESTS_DIR)/mksymtab.sh -t varlist.tmp $(ROMFS_DIR) >$@
|
||||
|
||||
# Clean each subdirectory
|
||||
|
||||
clean: $(foreach DIR, $(SUBDIRS), $(DIR)_clean)
|
||||
@rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB)
|
||||
clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean)
|
||||
@rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB_SRC) varlist.tmp
|
||||
@rm -rf $(ROMFS_DIR)
|
||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
@echo "CC: $<"
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
@echo "LD: $<"
|
||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
@echo "CC: $<"
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
@echo "LD: $<"
|
||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
@echo "CC: $<"
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
@echo "LD: $<"
|
||||
|
@ -1,6 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
usage="Usage: %0 <test-dir-path>"
|
||||
usage="Usage: $0 [-t <tmp-file>] <test-dir-path>"
|
||||
|
||||
# Check for the optional tempory file name
|
||||
|
||||
tmpfile=varlist.tmp
|
||||
if [ "X${1}" = "X-t" ]; then
|
||||
shift
|
||||
tmpfile=$1
|
||||
shift
|
||||
|
||||
if [ -z "$tmpfile" ]; then
|
||||
echo "ERROR: Missing <tmpfile>"
|
||||
echo ""
|
||||
echo $usage
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for the required ROMFS directory path
|
||||
|
||||
dir=$1
|
||||
if [ -z "$dir" ]; then
|
||||
@ -17,23 +35,33 @@ if [ ! -d "$dir" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
varlist=`find $dir -name "*-thunk.S"| xargs grep -h asciz | cut -f3 | sort | uniq`
|
||||
# Extract all of the undefined symbols from the ELF files and create a
|
||||
# list of sorted, unique undefined variable names.
|
||||
|
||||
echo "#ifndef __EXAMPLES_ELF_TESTS_SYMTAB_H"
|
||||
echo "#define __EXAMPLES_ELF_TESTS_SYMTAB_H"
|
||||
echo ""
|
||||
varlist=`find ${dir} -executable -type f | xargs nm | fgrep ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort | uniq`
|
||||
|
||||
# Now output the symbol table as a structure in a C source file. All
|
||||
# undefined symbols are declared as void* types. If the toolchain does
|
||||
# any kind of checking for function vs. data objects, then this could
|
||||
# faile
|
||||
|
||||
echo "#include <nuttx/compiler.h>"
|
||||
echo "#include <nuttx/binfmt/symtab.h>"
|
||||
echo ""
|
||||
echo "static const struct symtab_s exports[] = "
|
||||
|
||||
for var in $varlist; do
|
||||
echo "extern void *${var};"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "const struct symtab_s exports[] = "
|
||||
echo "{"
|
||||
|
||||
for string in $varlist; do
|
||||
var=`echo $string | sed -e "s/\"//g"`
|
||||
echo " {$string, $var},"
|
||||
for var in $varlist; do
|
||||
echo " {\"${var}\", &${var}},"
|
||||
done
|
||||
|
||||
echo "};"
|
||||
echo "#define NEXPORTS (sizeof(exports)/sizeof(struct symtab_s))"
|
||||
echo ""
|
||||
echo "#endif /* __EXAMPLES_ELF_TESTS_SYMTAB_H */"
|
||||
echo "const int nexports = sizeof(exports) / sizeof(struct symtab_s);"
|
||||
|
||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
@echo "CC: $<"
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
@echo "LD: $<"
|
||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
@echo "CC: $<"
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
@echo "LD: $<"
|
||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
@echo "CC: $<"
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
@echo "LD: $<"
|
||||
|
@ -38,6 +38,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
@ -66,22 +67,7 @@ static int sigusr2_rcvd = 0;
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sigusr1_sighandler
|
||||
****************************************************************************/
|
||||
|
||||
/* NOTE: it is necessary for functions that are referred to by function pointers
|
||||
* pointer to be declared with global scope (at least for ARM). Otherwise,
|
||||
* a relocation type that is not supported by ELF is generated by GCC.
|
||||
*/
|
||||
|
||||
void sigusr1_sighandler(int signo)
|
||||
{
|
||||
printf("sigusr1_sighandler: Received SIGUSR1, signo=%d\n", signo);
|
||||
sigusr1_rcvd = 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sigusr2_sigaction
|
||||
* Name: siguser_action
|
||||
***************************************************************************/
|
||||
|
||||
/* NOTE: it is necessary for functions that are referred to by function pointers
|
||||
@ -89,50 +75,33 @@ void sigusr1_sighandler(int signo)
|
||||
* a relocation type that is not supported by ELF is generated by GCC.
|
||||
*/
|
||||
|
||||
#ifdef __USE_POSIX199309
|
||||
void sigusr2_sigaction(int signo, siginfo_t *siginfo, void *arg)
|
||||
void siguser_action(int signo, siginfo_t *siginfo, void *arg)
|
||||
{
|
||||
printf("sigusr2_sigaction: Received SIGUSR2, signo=%d siginfo=%p arg=%p\n",
|
||||
printf("siguser_action: Received signo=%d siginfo=%p arg=%p\n",
|
||||
signo, siginfo, arg);
|
||||
|
||||
#ifdef HAVE_SIGQUEUE
|
||||
if (signo == SIGUSR1)
|
||||
{
|
||||
printf(" SIGUSR1 received\n");
|
||||
sigusr2_rcvd = 1;
|
||||
}
|
||||
else if (signo == SIGUSR2)
|
||||
{
|
||||
printf(" SIGUSR2 received\n");
|
||||
sigusr1_rcvd = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" ERROR: Unexpected signal\n");
|
||||
}
|
||||
|
||||
if (siginfo)
|
||||
{
|
||||
printf("siginfo:\n");
|
||||
printf(" si_signo = %d\n", siginfo->si_signo);
|
||||
printf(" si_errno = %d\n", siginfo->si_errno);
|
||||
printf(" si_code = %d\n", siginfo->si_code);
|
||||
printf(" si_pid = %d\n", siginfo->si_pid);
|
||||
printf(" si_uid = %d\n", siginfo->si_uid);
|
||||
printf(" si_status = %d\n", siginfo->si_status);
|
||||
printf(" si_utime = %ld\n", (long)siginfo->si_utime);
|
||||
printf(" si_stime = %ld\n", (long)siginfo->si_stime);
|
||||
printf(" si_value = %d\n", siginfo->si_value.sival_int);
|
||||
printf(" si_int = %d\n", siginfo->si_int);
|
||||
printf(" si_ptr = %p\n", siginfo->si_ptr);
|
||||
printf(" si_addr = %p\n", siginfo->si_addr);
|
||||
printf(" si_band = %ld\n", siginfo->si_band);
|
||||
printf(" si_fd = %d\n", siginfo->si_fd);
|
||||
}
|
||||
#endif
|
||||
sigusr2_rcvd = 1;
|
||||
}
|
||||
#else
|
||||
void sigusr2_sigaction(int signo)
|
||||
{
|
||||
printf("sigusr2_sigaction: Received SIGUSR2, signo=%d\n", signo);
|
||||
sigusr2_rcvd = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sigusr2_sighandler
|
||||
****************************************************************************/
|
||||
|
||||
static void sigusr2_sighandler(int signo)
|
||||
{
|
||||
printf("sigusr2_sighandler: Received SIGUSR2, signo=%d\n", signo);
|
||||
sigusr2_rcvd = 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -146,39 +115,36 @@ static void sigusr2_sighandler(int signo)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct sigaction act;
|
||||
struct sigaction oact;
|
||||
void (*old_sigusr1_sighandler)(int signo);
|
||||
void (*old_sigusr2_sighandler)(int signo);
|
||||
struct sigaction oact1;
|
||||
struct sigaction oact2;
|
||||
pid_t mypid = getpid();
|
||||
#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE)
|
||||
sigval_t sigval;
|
||||
#endif
|
||||
union sigval sigval;
|
||||
int status;
|
||||
|
||||
printf("Setting up signal handlers from pid=%d\n", mypid);
|
||||
|
||||
/* Set up so that sigusr1_sighandler will respond to SIGUSR1 */
|
||||
|
||||
old_sigusr1_sighandler = signal(SIGUSR1, sigusr1_sighandler);
|
||||
if (old_sigusr1_sighandler == SIG_ERR)
|
||||
{
|
||||
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||
errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Old SIGUSR1 sighandler at %p\n", old_sigusr1_sighandler);
|
||||
printf("New SIGUSR1 sighandler at %p\n", sigusr1_sighandler);
|
||||
|
||||
/* Set up so that sigusr2_sigaction will respond to SIGUSR2 */
|
||||
/* Set up so that siguser_action will respond to SIGUSR1 */
|
||||
|
||||
memset(&act, 0, sizeof(struct sigaction));
|
||||
act.sa_sigaction = sigusr2_sigaction;
|
||||
act.sa_sigaction = siguser_action;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
(void)sigemptyset(&act.sa_mask);
|
||||
|
||||
status = sigaction(SIGUSR2, &act, &oact);
|
||||
status = sigaction(SIGUSR1, &act, &oact1);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||
errno);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("Old SIGUSR1 sighandler at %p\n", oact1.sa_handler);
|
||||
printf("New SIGUSR1 sighandler at %p\n", siguser_action);
|
||||
|
||||
/* Set up so that siguser_action will respond to SIGUSR2 */
|
||||
|
||||
status = sigaction(SIGUSR2, &act, &oact2);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
||||
@ -186,18 +152,19 @@ int main(int argc, char **argv)
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("Old SIGUSR2 sighandler at %p\n", oact.sa_handler);
|
||||
printf("New SIGUSR2 sighandler at %p\n", sigusr2_sigaction);
|
||||
printf("Raising SIGUSR1 from pid=%d\n", mypid);
|
||||
printf("Old SIGUSR2 sighandler at %p\n", oact2.sa_handler);
|
||||
printf("New SIGUSR2 sighandler at %p\n", siguser_action);
|
||||
printf("Raising SIGUSR1 from pid=%d\n", mypid);
|
||||
|
||||
fflush(stdout); usleep(SHORT_DELAY);
|
||||
|
||||
/* Send SIGUSR1 to ourselves via raise() */
|
||||
/* Send SIGUSR1 to ourselves via kill() */
|
||||
|
||||
status = raise(SIGUSR1);
|
||||
printf("Kill-ing SIGUSR1 from pid=%d\n", mypid);
|
||||
status = kill(0, SIGUSR1);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to raise SIGUSR1, errno=%d\n", errno);
|
||||
fprintf(stderr, "Failed to kill SIGUSR1, errno=%d\n", errno);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
@ -211,14 +178,14 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "SIGUSR1 not received\n");
|
||||
exit(4);
|
||||
}
|
||||
|
||||
sigusr1_rcvd = 0;
|
||||
|
||||
/* Send SIGUSR2 to ourselves */
|
||||
|
||||
printf("Killing SIGUSR2 from pid=%d\n", mypid);
|
||||
printf("sigqueue-ing SIGUSR2 from pid=%d\n", mypid);
|
||||
fflush(stdout); usleep(SHORT_DELAY);
|
||||
|
||||
#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE)
|
||||
/* Send SIGUSR2 to ourselves via sigqueue() */
|
||||
|
||||
sigval.sival_int = 87;
|
||||
@ -230,20 +197,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
usleep(SHORT_DELAY);
|
||||
printf("SIGUSR2 queued from pid=%d, sigval=97\n", mypid);
|
||||
#else
|
||||
/* Send SIGUSR2 to ourselves via kill() */
|
||||
printf("SIGUSR2 queued from pid=%d, sigval=87\n", mypid);
|
||||
|
||||
status = kill(mypid, SIGUSR2);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to kill SIGUSR2, errno=%d\n", errno);
|
||||
exit(5);
|
||||
}
|
||||
|
||||
usleep(SHORT_DELAY);
|
||||
printf("SIGUSR2 killed from pid=%d\n", mypid);
|
||||
#endif
|
||||
/* Verify that SIGUSR2 was received */
|
||||
|
||||
if (sigusr2_rcvd == 0)
|
||||
@ -251,32 +206,33 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "SIGUSR2 not received\n");
|
||||
exit(6);
|
||||
}
|
||||
|
||||
sigusr2_rcvd = 0;
|
||||
|
||||
/* Remove the sigusr2_sigaction handler and replace the SIGUSR2
|
||||
/* Remove the siguser_action handler and replace the SIGUSR2
|
||||
* handler with sigusr2_sighandler.
|
||||
*/
|
||||
|
||||
printf("Resetting SIGUSR2 signal handler from pid=%d\n", mypid);
|
||||
|
||||
old_sigusr2_sighandler = signal(SIGUSR2, sigusr2_sighandler);
|
||||
if (old_sigusr2_sighandler == SIG_ERR)
|
||||
status = sigaction(SIGUSR2, &oact2, &act);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
||||
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||
errno);
|
||||
exit(7);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("Old SIGUSR2 sighandler at %p\n", old_sigusr2_sighandler);
|
||||
printf("New SIGUSR2 sighandler at %p\n", sigusr2_sighandler);
|
||||
printf("Old SIGUSR1 sighandler at %p\n", act.sa_handler);
|
||||
printf("New SIGUSR1 sighandler at %p\n", oact1.sa_handler);
|
||||
|
||||
/* Verify that the handler that was removed was sigusr2_sigaction */
|
||||
/* Verify that the handler that was removed was siguser_action */
|
||||
|
||||
if ((void*)old_sigusr2_sighandler != (void*)sigusr2_sigaction)
|
||||
if ((void*)act.sa_handler != (void*)siguser_action)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Old SIGUSR2 signhanlder (%p) is not sigusr2_sigation (%p)\n",
|
||||
old_sigusr2_sighandler, sigusr2_sigaction);
|
||||
"Old SIGUSR2 signal handler (%p) is not siguser_action (%p)\n",
|
||||
act.sa_handler, siguser_action);
|
||||
exit(8);
|
||||
}
|
||||
|
||||
@ -302,6 +258,7 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "SIGUSR2 not received\n");
|
||||
exit(10);
|
||||
}
|
||||
|
||||
sigusr2_rcvd = 0;
|
||||
|
||||
return 0;
|
||||
|
@ -36,7 +36,7 @@
|
||||
-include $(TOPDIR)/.config
|
||||
-include $(TOPDIR)/Make.defs
|
||||
|
||||
CFLAGS += -I.
|
||||
CELFFLAGS += -I.
|
||||
|
||||
BIN = struct
|
||||
SRCS = struct_main.c struct_dummy.c
|
||||
@ -46,7 +46,7 @@ all: $(BIN)
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
@echo "CC: $<"
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
@echo "LD: $<"
|
||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
@echo "CC: $<"
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
@echo "LD: $<"
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
usage="Usage: %0 <test-dir-path>"
|
||||
usage="Usage: $0 <test-dir-path>"
|
||||
|
||||
dir=$1
|
||||
if [ -z "$dir" ]; then
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* examples/nxflat/tests/signal/signal.c
|
||||
*
|
||||
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -67,73 +67,41 @@ static int sigusr2_rcvd = 0;
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sigusr1_sighandler
|
||||
****************************************************************************/
|
||||
|
||||
/* NOTE: it is necessary for functions that are referred to by function pointers
|
||||
* pointer to be declared with global scope (at least for ARM). Otherwise,
|
||||
* a relocation type that is not supported by NXFLAT is generated by GCC.
|
||||
*/
|
||||
|
||||
void sigusr1_sighandler(int signo)
|
||||
{
|
||||
printf("sigusr1_sighandler: Received SIGUSR1, signo=%d\n", signo);
|
||||
sigusr1_rcvd = 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sigusr2_sigaction
|
||||
* Name: siguser_action
|
||||
***************************************************************************/
|
||||
|
||||
/* NOTE: it is necessary for functions that are referred to by function pointers
|
||||
* pointer to be declared with global scope (at least for ARM). Otherwise,
|
||||
* a relocation type that is not supported by NXFLAT is generated by GCC.
|
||||
* a relocation type that is not supported by ELF is generated by GCC.
|
||||
*/
|
||||
|
||||
#ifdef __USE_POSIX199309
|
||||
void sigusr2_sigaction(int signo, siginfo_t *siginfo, void *arg)
|
||||
void siguser_action(int signo, siginfo_t *siginfo, void *arg)
|
||||
{
|
||||
printf("sigusr2_sigaction: Received SIGUSR2, signo=%d siginfo=%p arg=%p\n",
|
||||
printf("siguser_action: Received signo=%d siginfo=%p arg=%p\n",
|
||||
signo, siginfo, arg);
|
||||
|
||||
#ifdef HAVE_SIGQUEUE
|
||||
if (signo == SIGUSR1)
|
||||
{
|
||||
printf(" SIGUSR1 received\n");
|
||||
sigusr2_rcvd = 1;
|
||||
}
|
||||
else if (signo == SIGUSR2)
|
||||
{
|
||||
printf(" SIGUSR2 received\n");
|
||||
sigusr1_rcvd = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" ERROR: Unexpected signal\n");
|
||||
}
|
||||
|
||||
if (siginfo)
|
||||
{
|
||||
printf("siginfo:\n");
|
||||
printf(" si_signo = %d\n", siginfo->si_signo);
|
||||
printf(" si_errno = %d\n", siginfo->si_errno);
|
||||
printf(" si_code = %d\n", siginfo->si_code);
|
||||
printf(" si_pid = %d\n", siginfo->si_pid);
|
||||
printf(" si_uid = %d\n", siginfo->si_uid);
|
||||
printf(" si_status = %d\n", siginfo->si_status);
|
||||
printf(" si_utime = %ld\n", (long)siginfo->si_utime);
|
||||
printf(" si_stime = %ld\n", (long)siginfo->si_stime);
|
||||
printf(" si_value = %d\n", siginfo->si_value.sival_int);
|
||||
printf(" si_int = %d\n", siginfo->si_int);
|
||||
printf(" si_ptr = %p\n", siginfo->si_ptr);
|
||||
printf(" si_addr = %p\n", siginfo->si_addr);
|
||||
printf(" si_band = %ld\n", siginfo->si_band);
|
||||
printf(" si_fd = %d\n", siginfo->si_fd);
|
||||
}
|
||||
#endif
|
||||
sigusr2_rcvd = 1;
|
||||
}
|
||||
#else
|
||||
void sigusr2_sigaction(int signo)
|
||||
{
|
||||
printf("sigusr2_sigaction: Received SIGUSR2, signo=%d\n", signo);
|
||||
sigusr2_rcvd = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sigusr2_sighandler
|
||||
****************************************************************************/
|
||||
|
||||
static void sigusr2_sighandler(int signo)
|
||||
{
|
||||
printf("sigusr2_sighandler: Received SIGUSR2, signo=%d\n", signo);
|
||||
sigusr2_rcvd = 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -147,39 +115,36 @@ static void sigusr2_sighandler(int signo)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct sigaction act;
|
||||
struct sigaction oact;
|
||||
void (*old_sigusr1_sighandler)(int signo);
|
||||
void (*old_sigusr2_sighandler)(int signo);
|
||||
struct sigaction oact1;
|
||||
struct sigaction oact2;
|
||||
pid_t mypid = getpid();
|
||||
#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE)
|
||||
sigval_t sigval;
|
||||
#endif
|
||||
union sigval sigval;
|
||||
int status;
|
||||
|
||||
printf("Setting up signal handlers from pid=%d\n", mypid);
|
||||
|
||||
/* Set up so that sigusr1_sighandler will respond to SIGUSR1 */
|
||||
|
||||
old_sigusr1_sighandler = signal(SIGUSR1, sigusr1_sighandler);
|
||||
if (old_sigusr1_sighandler == SIG_ERR)
|
||||
{
|
||||
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||
errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Old SIGUSR1 sighandler at %p\n", old_sigusr1_sighandler);
|
||||
printf("New SIGUSR1 sighandler at %p\n", sigusr1_sighandler);
|
||||
|
||||
/* Set up so that sigusr2_sigaction will respond to SIGUSR2 */
|
||||
/* Set up so that siguser_action will respond to SIGUSR1 */
|
||||
|
||||
memset(&act, 0, sizeof(struct sigaction));
|
||||
act.sa_sigaction = sigusr2_sigaction;
|
||||
act.sa_sigaction = siguser_action;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
(void)sigemptyset(&act.sa_mask);
|
||||
|
||||
status = sigaction(SIGUSR2, &act, &oact);
|
||||
status = sigaction(SIGUSR1, &act, &oact1);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||
errno);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("Old SIGUSR1 sighandler at %p\n", oact1.sa_handler);
|
||||
printf("New SIGUSR1 sighandler at %p\n", siguser_action);
|
||||
|
||||
/* Set up so that siguser_action will respond to SIGUSR2 */
|
||||
|
||||
status = sigaction(SIGUSR2, &act, &oact2);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
||||
@ -187,18 +152,19 @@ int main(int argc, char **argv)
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("Old SIGUSR2 sighandler at %p\n", oact.sa_handler);
|
||||
printf("New SIGUSR2 sighandler at %p\n", sigusr2_sigaction);
|
||||
printf("Raising SIGUSR1 from pid=%d\n", mypid);
|
||||
printf("Old SIGUSR2 sighandler at %p\n", oact2.sa_handler);
|
||||
printf("New SIGUSR2 sighandler at %p\n", siguser_action);
|
||||
printf("Raising SIGUSR1 from pid=%d\n", mypid);
|
||||
|
||||
fflush(stdout); usleep(SHORT_DELAY);
|
||||
|
||||
/* Send SIGUSR1 to ourselves via raise() */
|
||||
/* Send SIGUSR1 to ourselves via kill() */
|
||||
|
||||
status = raise(SIGUSR1);
|
||||
printf("Kill-ing SIGUSR1 from pid=%d\n", mypid);
|
||||
status = kill(0, SIGUSR1);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to raise SIGUSR1, errno=%d\n", errno);
|
||||
fprintf(stderr, "Failed to kill SIGUSR1, errno=%d\n", errno);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
@ -212,14 +178,14 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "SIGUSR1 not received\n");
|
||||
exit(4);
|
||||
}
|
||||
|
||||
sigusr1_rcvd = 0;
|
||||
|
||||
/* Send SIGUSR2 to ourselves */
|
||||
|
||||
printf("Killing SIGUSR2 from pid=%d\n", mypid);
|
||||
printf("sigqueue-ing SIGUSR2 from pid=%d\n", mypid);
|
||||
fflush(stdout); usleep(SHORT_DELAY);
|
||||
|
||||
#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE)
|
||||
/* Send SIGUSR2 to ourselves via sigqueue() */
|
||||
|
||||
sigval.sival_int = 87;
|
||||
@ -231,20 +197,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
usleep(SHORT_DELAY);
|
||||
printf("SIGUSR2 queued from pid=%d, sigval=97\n", mypid);
|
||||
#else
|
||||
/* Send SIGUSR2 to ourselves via kill() */
|
||||
printf("SIGUSR2 queued from pid=%d, sigval=87\n", mypid);
|
||||
|
||||
status = kill(mypid, SIGUSR2);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to kill SIGUSR2, errno=%d\n", errno);
|
||||
exit(5);
|
||||
}
|
||||
|
||||
usleep(SHORT_DELAY);
|
||||
printf("SIGUSR2 killed from pid=%d\n", mypid);
|
||||
#endif
|
||||
/* Verify that SIGUSR2 was received */
|
||||
|
||||
if (sigusr2_rcvd == 0)
|
||||
@ -252,32 +206,33 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "SIGUSR2 not received\n");
|
||||
exit(6);
|
||||
}
|
||||
|
||||
sigusr2_rcvd = 0;
|
||||
|
||||
/* Remove the sigusr2_sigaction handler and replace the SIGUSR2
|
||||
/* Remove the siguser_action handler and replace the SIGUSR2
|
||||
* handler with sigusr2_sighandler.
|
||||
*/
|
||||
|
||||
printf("Resetting SIGUSR2 signal handler from pid=%d\n", mypid);
|
||||
|
||||
old_sigusr2_sighandler = signal(SIGUSR2, sigusr2_sighandler);
|
||||
if (old_sigusr2_sighandler == SIG_ERR)
|
||||
status = sigaction(SIGUSR2, &oact2, &act);
|
||||
if (status != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
||||
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||
errno);
|
||||
exit(7);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("Old SIGUSR2 sighandler at %p\n", old_sigusr2_sighandler);
|
||||
printf("New SIGUSR2 sighandler at %p\n", sigusr2_sighandler);
|
||||
printf("Old SIGUSR1 sighandler at %p\n", act.sa_handler);
|
||||
printf("New SIGUSR1 sighandler at %p\n", oact1.sa_handler);
|
||||
|
||||
/* Verify that the handler that was removed was sigusr2_sigaction */
|
||||
/* Verify that the handler that was removed was siguser_action */
|
||||
|
||||
if ((void*)old_sigusr2_sighandler != (void*)sigusr2_sigaction)
|
||||
if ((void*)act.sa_handler != (void*)siguser_action)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Old SIGUSR2 signhanlder (%p) is not sigusr2_sigation (%p)\n",
|
||||
old_sigusr2_sighandler, sigusr2_sigaction);
|
||||
"Old SIGUSR2 signal handler (%p) is not siguser_action (%p)\n",
|
||||
act.sa_handler, siguser_action);
|
||||
exit(8);
|
||||
}
|
||||
|
||||
@ -303,6 +258,7 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "SIGUSR2 not received\n");
|
||||
exit(10);
|
||||
}
|
||||
|
||||
sigusr2_rcvd = 0;
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user