summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-29 00:52:23 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-29 00:52:23 +0000
commitade5fb42679b7e890f29487ca850c65f9944fa1e (patch)
tree84f10662c214892091c5b7d5dce796b6f736c6b4
parent09dcebb6991350498b809a20b55fbcfd982a0b2a (diff)
downloadpx4-nuttx-ade5fb42679b7e890f29487ca850c65f9944fa1e.tar.gz
px4-nuttx-ade5fb42679b7e890f29487ca850c65f9944fa1e.tar.bz2
px4-nuttx-ade5fb42679b7e890f29487ca850c65f9944fa1e.zip
Finish implemention of ELF loader static constructor support. Still some issues.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5272 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--apps/examples/README.txt2
-rw-r--r--apps/examples/elf/tests/Makefile8
-rw-r--r--apps/examples/elf/tests/hello++/Makefile116
-rw-r--r--apps/examples/elf/tests/hello++/hello++1.cpp60
-rw-r--r--apps/examples/elf/tests/hello++/hello++2.cpp123
-rw-r--r--apps/examples/elf/tests/hello++/hello++3.cpp132
-rw-r--r--apps/examples/elf/tests/hello++/hello++4.cpp150
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_elf.c2
-rw-r--r--nuttx/binfmt/elf.c1
-rw-r--r--nuttx/binfmt/libelf/Make.defs2
-rw-r--r--nuttx/binfmt/libelf/libelf.h45
-rw-r--r--nuttx/binfmt/libelf/libelf_bind.c15
-rw-r--r--nuttx/binfmt/libelf/libelf_ctors.c274
-rw-r--r--nuttx/binfmt/libelf/libelf_iobuffer.c136
-rw-r--r--nuttx/binfmt/libelf/libelf_load.c29
-rw-r--r--nuttx/binfmt/libelf/libelf_symbols.c17
-rw-r--r--nuttx/binfmt/libelf/libelf_uninit.c50
-rw-r--r--nuttx/binfmt/libelf/libelf_unload.c21
-rw-r--r--nuttx/configs/stm32f4discovery/elf/Make.defs2
-rw-r--r--nuttx/configs/stm32f4discovery/elf/defconfig270
-rw-r--r--nuttx/include/nuttx/binfmt/elf.h5
21 files changed, 532 insertions, 928 deletions
diff --git a/apps/examples/README.txt b/apps/examples/README.txt
index abf95e208..907467bb1 100644
--- a/apps/examples/README.txt
+++ b/apps/examples/README.txt
@@ -323,6 +323,8 @@ examples/elf
CELFFLAGS = $(CFLAGS) -mlong-calls
+ Similarly for C++ flags which must be provided in CXXELFFLAGS.
+
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).
diff --git a/apps/examples/elf/tests/Makefile b/apps/examples/elf/tests/Makefile
index f834f6c78..d2192cb1e 100644
--- a/apps/examples/elf/tests/Makefile
+++ b/apps/examples/elf/tests/Makefile
@@ -33,13 +33,15 @@
#
############################################################################
-# Most of these do no build yet
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
-ALL_SUBDIRS = errno hello hello++ longjmp mutex pthread signal task struct
+ALL_SUBDIRS = errno hello helloxx longjmp mutex pthread signal task struct
BUILD_SUBDIRS = errno hello task struct
ifeq ($(CONFIG_HAVE_CXX),y)
-BUILD_SUBDIRS += hello++
+BUILD_SUBDIRS += helloxx
endif
ifeq ($(CONFIG_EXAMPLES_ELF_LONGJMP),y)
diff --git a/apps/examples/elf/tests/hello++/Makefile b/apps/examples/elf/tests/hello++/Makefile
deleted file mode 100644
index 9de52cfa1..000000000
--- a/apps/examples/elf/tests/hello++/Makefile
+++ /dev/null
@@ -1,116 +0,0 @@
-############################################################################
-# examples/elf/tests/hello/Makefile
-#
-# Copyright (C) 2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-# 3. Neither the name NuttX nor the names of its contributors may be
-# used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-############################################################################
-
--include $(TOPDIR)/.config
--include $(TOPDIR)/Make.defs
-
-BIN1 = hello++1
-BIN2 = hello++2
-BIN3 = hello++3
-#BIN4 = hello++4
-ALL_BIN = $(BIN1) $(BIN2) $(BIN3) $(BIN4)
-
-SRCS1 = $(BIN1).c
-OBJS1 = $(SRCS1:.c=.o)
-
-SRCS2 = $(BIN2).c
-OBJS2 = $(SRCS2:.c=.o)
-
-SRCS3 = $(BIN3).c
-OBJS3 = $(SRCS3:.c=.o)
-
-#SRCS4 = $(BIN4).c
-#OBJS4 = $(SRCS4:.c=.o)
-
-SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4)
-OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4)
-
-LIBSTDC_STUBS_DIR = $(TOPDIR)/libxx
-LIBSTDC_STUBS_LIB = $(LIBSTDC_STUBS_DIR)/liblibxx.a
-
-all: $(BIN1) $(BIN2) $(BIN3) $(BIN4)
-
-$(OBJS): %.o: %.cpp
- @echo "CC: $<"
- @$(CXX) -c $(CXXFLAGS) $< -o $@
-
-# This contains libstdc++ stubs to that you can build C++ code
-# without actually having libstdc++
-
-$(LIBSTDC_STUBS_LIB):
- @$(MAKE) -C $(LIBSTDC_STUBS_DIR) TOPDIR=$(TOPDIR)
-
-# BIN1 and BIN2 link just like C code because they contain no
-# static constructors. BIN1 is equivalent to a C hello world;
-# BIN2 contains a class that implements hello world, but it is
-# not statically initialized.
-
-$(BIN1): $(OBJS1)
- @echo "LD: $<"
- @$(LD) $(LDELFFLAGS) -o $@ $^
-
-$(BIN2): $(OBJS2)
- @echo "LD: $<"
- @$(LD) $(LDELFFLAGS) -o $@ $^
-
-# BIN3 is equivalent to BIN2 except that is uses static initializers
-
-$(BIN3): $(OBJS3)
- @echo "LD: $<"
- @$(LD) $(LDELFFLAGS) -o $@ $^
-
-# BIN4 is similar to BIN3 except that it uses the streams code from libstdc++
-#
-# NOTE: libstdc++ is not available for NuttX as of this writing
-#
-#$(BIN4): $(OBJS4)
-# @echo "LD: $<"
-# @$(LD) $(LDELFFLAGS) -o $@ $^
-
-clean:
- @rm -f $(ALL_BIN) *.o *~ .*.swp core
-
-install: $(ALL_BIN)
- @install -D $(BIN1) $(ROMFS_DIR)/$(BIN1)
- @install -D $(BIN2) $(ROMFS_DIR)/$(BIN2)
- @install -D $(BIN3) $(ROMFS_DIR)/$(BIN3)
-# @install -D $(BIN4) $(ROMFS_DIR)/$(BIN4)
-
-
-
-
-
-
-
diff --git a/apps/examples/elf/tests/hello++/hello++1.cpp b/apps/examples/elf/tests/hello++/hello++1.cpp
deleted file mode 100644
index 22a728188..000000000
--- a/apps/examples/elf/tests/hello++/hello++1.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// examples/elf/tests/hello++/hello++1.c
-//
-// Copyright (C) 2012 Gregory Nutt. All rights reserved.
-// Author: Gregory Nutt <gnutt@nuttx.org>
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the
-// distribution.
-// 3. Neither the name NuttX nor the names of its contributors may be
-// used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-/////////////////////////////////////////////////////////////////////////////
-//
-// This is an trivial version of "Hello, World" program. It illustrates
-// that we can build C programs using the C++ compiler.
-//
-// - Building a C++ program to use the C library
-// - No class creation
-// - NO Streams
-// - NO Static constructor and destructors
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////
-// Included Files
-/////////////////////////////////////////////////////////////////////////////
-
-#include <cstdio>
-
-/////////////////////////////////////////////////////////////////////////////
-// Public Functions
-/////////////////////////////////////////////////////////////////////////////
-
-int main(int argc, char **argv)
-{
- printf("Hello, World!\n");
- return 0;
-}
diff --git a/apps/examples/elf/tests/hello++/hello++2.cpp b/apps/examples/elf/tests/hello++/hello++2.cpp
deleted file mode 100644
index a8ba589bd..000000000
--- a/apps/examples/elf/tests/hello++/hello++2.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// examples/elf/tests/hello++/hello++2.c
-//
-// Copyright (C) 2012 Gregory Nutt. All rights reserved.
-// Author: Gregory Nutt <gnutt@nuttx.org>
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the
-// distribution.
-// 3. Neither the name NuttX nor the names of its contributors may be
-// used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-/////////////////////////////////////////////////////////////////////////////
-//
-// This is an another trivial version of "Hello, World" design. It illustrates
-//
-// - Building a C++ program to use the C library
-// - Basic class creation
-// - NO Streams
-// - NO Static constructor and destructors
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////
-// Included Files
-/////////////////////////////////////////////////////////////////////////////
-
-#include <cstdio>
-
-/////////////////////////////////////////////////////////////////////////////
-// Classes
-/////////////////////////////////////////////////////////////////////////////
-
-class CThingSayer
-{
- const char *szWhatToSay;
-public:
- CThingSayer(void)
- {
- printf("CThingSayer::CThingSayer: I am!\n");
- szWhatToSay = (const char*)NULL;
- }
-
- ~CThingSayer(void)
- {
- printf("CThingSayer::~CThingSayer: I cease to be\n");
- if (szWhatToSay)
- {
- printf("CThingSayer::~CThingSayer: I will never say '%s' again\n",
- szWhatToSay);
- }
- szWhatToSay = (const char*)NULL;
- }
-
- void Initialize(const char *czSayThis)
- {
- printf("CThingSayer::Initialize: When told, I will say '%s'\n",
- czSayThis);
- szWhatToSay = czSayThis;
- }
-
- void SayThing(void)
- {
- printf("CThingSayer::SayThing: I am now saying '%s'\n", szWhatToSay);
- }
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// Public Functions
-/////////////////////////////////////////////////////////////////////////////
-
-int main(int argc, char **argv)
-{
- CThingSayer *MyThingSayer;
-
- printf("main: Started. Creating MyThingSayer\n");
-
- // Create an instance of the CThingSayer class
- // We should see the message from constructor, CThingSayer::CThingSayer(),
-
- MyThingSayer = new CThingSayer;
- printf("main: Created MyThingSayer=0x%08lx\n", (long)MyThingSayer);
-
- // Tell MyThingSayer that "Hello, World!" is the string to be said
-
- printf("main: Calling MyThingSayer->Initialize\n");;
- MyThingSayer->Initialize("Hello, World!");
-
- // Tell MyThingSayer to say the thing we told it to say
-
- printf("main: Calling MyThingSayer->SayThing\n");;
- MyThingSayer->SayThing();
-
- // We should see the message from the destructor,
- // CThingSayer::~CThingSayer(), AFTER we see the following
-
- printf("main: Destroying MyThingSayer\n");
- delete MyThingSayer;
-
- printf("main: Returning\n");;
- return 0;
-}
diff --git a/apps/examples/elf/tests/hello++/hello++3.cpp b/apps/examples/elf/tests/hello++/hello++3.cpp
deleted file mode 100644
index eedaa6df0..000000000
--- a/apps/examples/elf/tests/hello++/hello++3.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// examples/elf/tests/hello++/hello++3.c
-//
-// Copyright (C) 2012 Gregory Nutt. All rights reserved.
-// Author: Gregory Nutt <gnutt@nuttx.org>
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the
-// distribution.
-// 3. Neither the name NuttX nor the names of its contributors may be
-// used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-/////////////////////////////////////////////////////////////////////////////
-//
-// This is an another trivial version of "Hello, World" design. It illustrates
-//
-// - Building a C++ program to use the C library and stdio
-// - Basic class creation with virtual methods.
-// - Static constructor and destructors (in main program only)
-// - NO Streams
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////
-// Included Files
-/////////////////////////////////////////////////////////////////////////////
-
-#include <cstdio>
-
-/////////////////////////////////////////////////////////////////////////////
-// Classes
-/////////////////////////////////////////////////////////////////////////////
-
-class CThingSayer
-{
- const char *szWhatToSay;
-public:
- CThingSayer(void);
- virtual ~CThingSayer(void);
- virtual void Initialize(const char *czSayThis);
- virtual void SayThing(void);
-};
-
-// A static instance of the CThingSayer class. This instance MUST
-// be constructed by the system BEFORE the program is started at
-// main() and must be destructed by the system AFTER the main()
-// returns to the system
-
-static CThingSayer MyThingSayer;
-
-// These are implementations of the methods of the CThingSayer class
-
-CThingSayer::CThingSayer(void)
-{
- printf("CThingSayer::CThingSayer: I am!\n");
- szWhatToSay = (const char*)NULL;
-}
-
-CThingSayer::~CThingSayer(void)
-{
- printf("CThingSayer::~CThingSayer: I cease to be\n");
- if (szWhatToSay)
- {
- printf("CThingSayer::~CThingSayer: I will never say '%s' again\n",
- szWhatToSay);
- }
- szWhatToSay = (const char*)NULL;
-}
-
-void CThingSayer::Initialize(const char *czSayThis)
-{
- printf("CThingSayer::Initialize: When told, I will say '%s'\n",
- czSayThis);
- szWhatToSay = czSayThis;
-}
-
-void CThingSayer::SayThing(void)
-{
- printf("CThingSayer::SayThing: I am now saying '%s'\n", szWhatToSay);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Public Functions
-/////////////////////////////////////////////////////////////////////////////
-
-int main(int argc, char **argv)
-{
- // We should see the message from constructor, CThingSayer::CThingSayer(),
- // BEFORE we see the following messages. That is proof that the
- // C++ static initializer is working
-
- printf("main: Started. MyThingSayer should already exist\n");
-
- // Tell MyThingSayer that "Hello, World!" is the string to be said
-
- printf("main: Calling MyThingSayer.Initialize\n");;
- MyThingSayer.Initialize("Hello, World!");
-
- // Tell MyThingSayer to say the thing we told it to say
-
- printf("main: Calling MyThingSayer.SayThing\n");;
- MyThingSayer.SayThing();
-
- // We are finished, return. We should see the message from the
- // destructor, CThingSayer::~CThingSayer(), AFTER we see the following
- // message. That is proof that the C++ static destructor logic
- // is working
-
- printf("main: Returning. MyThingSayer should be destroyed\n");;
- return 0;
-}
diff --git a/apps/examples/elf/tests/hello++/hello++4.cpp b/apps/examples/elf/tests/hello++/hello++4.cpp
deleted file mode 100644
index 1a9f2e28b..000000000
--- a/apps/examples/elf/tests/hello++/hello++4.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// examples/elf/tests/hello++/hello++4.c
-//
-// Copyright (C) 2012 Gregory Nutt. All rights reserved.
-// Author: Gregory Nutt <gnutt@nuttx.org>
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the
-// distribution.
-// 3. Neither the name NuttX nor the names of its contributors may be
-// used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-/////////////////////////////////////////////////////////////////////////////
-//
-// This is an excessively complex version of "Hello, World" design to
-// illustrate some basic properties of C++:
-//
-// - Building a C++ program
-// - Streams / statically linked libstdc++
-// - Static constructor and destructors (in main program only)
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////
-// Included Files
-/////////////////////////////////////////////////////////////////////////////
-
-#include <cstdio>
-#include <iostream>
-
-#ifndef NULL
-# define NULL ((void*)0L)
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-// Classes
-/////////////////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-// A hello world sayer class
-
-class CThingSayer
-{
- const char *szWhatToSay;
-public:
- CThingSayer(void);
- virtual ~CThingSayer(void);
- virtual void Initialize(const char *czSayThis);
- virtual void SayThing(void);
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// Private Data
-/////////////////////////////////////////////////////////////////////////////
-
-// A static instance of the CThingSayer class. This instance MUST
-// be constructed by the system BEFORE the program is started at
-// main() and must be destructed by the system AFTER the main()
-// returns to the system
-
-static CThingSayer MyThingSayer;
-
-/////////////////////////////////////////////////////////////////////////////
-// Method Implementations
-/////////////////////////////////////////////////////////////////////////////
-
-// These are implementations of the methods of the CThingSayer class
-
-CThingSayer::CThingSayer(void)
-{
- cout << "CThingSayer::CThingSayer: I am!" << endl;
- szWhatToSay = (const char*)NULL;
-}
-
-CThingSayer::~CThingSayer(void)
-{
- cout << "CThingSayer::~CThingSayer: I cease to be" << endl;
- if (szWhatToSay)
- {
- cout << "CThingSayer::~CThingSayer: I will never say '"
- << szWhatToSay << "' again" << endl;
- }
- szWhatToSay = (const char*)NULL;
-}
-
-void CThingSayer::Initialize(const char *czSayThis)
-{
- cout << "CThingSayer::Initialize: When told, I will say '"
- << czSayThis << "'" << endl;
- szWhatToSay = czSayThis;
-}
-
-void CThingSayer::SayThing(void)
-{
- cout << "CThingSayer::SayThing: I am now saying '"
- << szWhatToSay << "'" << endl;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Public Functions
-/////////////////////////////////////////////////////////////////////////////
-
-int main(int argc, char **argv)
-{
- // We should see the message from constructor, CThingSayer::CThingSayer(),
- // BEFORE we see the following messages. That is proof that the
- // C++ static initializer is working
-
- cout << "main: Started" << endl;
-
- // Tell MyThingSayer that "Hello, World!" is the string to be said
-
- cout << "main: Calling MyThingSayer.Initialize" << endl;
- MyThingSayer.Initialize("Hello, World!");
-
- // Tell MyThingSayer to say the thing we told it to say
-
- cout << "main: Calling MyThingSayer.SayThing" << endl;
- MyThingSayer.SayThing();
-
- // We are finished, return. We should see the message from the
- // destructor, CThingSayer::~CThingSayer(), AFTER we see the following
- // message. That is proof that the C++ static destructor logic
- // is working
-
- cout << "main: Returning" << endl;
- return 0;
-}
diff --git a/nuttx/arch/arm/src/armv7-m/up_elf.c b/nuttx/arch/arm/src/armv7-m/up_elf.c
index 202c902b4..1cc1fa32a 100644
--- a/nuttx/arch/arm/src/armv7-m/up_elf.c
+++ b/nuttx/arch/arm/src/armv7-m/up_elf.c
@@ -282,7 +282,7 @@ int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym,
if (offset <= (int32_t)0xff000000 || offset >= (int32_t)0x01000000)
{
- bdbg(" ERROR: JUMP24 [%d] relocation out of range, offset=%08lx\n",
+ bdbg(" ERROR: JUMP24 [%d] relocation out of range, branch taget=%08lx\n",
ELF32_R_TYPE(rel->r_info), offset);
return -EINVAL;
diff --git a/nuttx/binfmt/elf.c b/nuttx/binfmt/elf.c
index 9a0ac1873..57123ed95 100644
--- a/nuttx/binfmt/elf.c
+++ b/nuttx/binfmt/elf.c
@@ -116,6 +116,7 @@ static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo)
bdbg(" filelen: %ld\n", (long)loadinfo->filelen);
#ifdef CONFIG_ELF_CONSTRUCTORS
bdbg(" ctors: %08lx\n", (long)loadinfo->ctors);
+ bdbg(" nctors: %d\n", loadinfo->nctors);
#endif
bdbg(" filfd: %d\n", loadinfo->filfd);
bdbg(" symtabidx: %d\n", loadinfo->symtabidx);
diff --git a/nuttx/binfmt/libelf/Make.defs b/nuttx/binfmt/libelf/Make.defs
index a70a127f8..cf2507a99 100644
--- a/nuttx/binfmt/libelf/Make.defs
+++ b/nuttx/binfmt/libelf/Make.defs
@@ -43,7 +43,7 @@ BINFMT_CSRCS += elf.c
BINFMT_CSRCS += libelf_init.c libelf_uninit.c libelf_load.c \
libelf_unload.c libelf_verify.c libelf_read.c \
- libelf_bind.c libelf_symbols.c
+ libelf_bind.c libelf_symbols.c libelf_iobuffer.c
ifeq ($(CONFIG_ELF_CONSTRUCTORS),y)
BINFMT_CSRCS += libelf_ctors.c
diff --git a/nuttx/binfmt/libelf/libelf.h b/nuttx/binfmt/libelf/libelf.h
index 0fb1362dc..0d13515cc 100644
--- a/nuttx/binfmt/libelf/libelf.h
+++ b/nuttx/binfmt/libelf/libelf.h
@@ -142,6 +142,49 @@ int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
FAR const struct symtab_s *exports, int nexports);
/****************************************************************************
+ * Name: elf_freebuffers
+ *
+ * Description:
+ * Release all working buffers.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_freebuffers(FAR struct elf_loadinfo_s *loadinfo);
+
+/****************************************************************************
+ * Name: elf_allocbuffer
+ *
+ * Description:
+ * Perform the initial allocation of the I/O buffer, if it has not already
+ * been allocated.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_allocbuffer(FAR struct elf_loadinfo_s *loadinfo);
+
+/****************************************************************************
+ * Name: elf_reallocbuffer
+ *
+ * Description:
+ * Increase the size of I/O buffer by the specified buffer increment.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_reallocbuffer(FAR struct elf_loadinfo_s *loadinfo, size_t increment);
+
+/****************************************************************************
* Name: elf_findctors
*
* Description:
@@ -157,7 +200,7 @@ int elf_symvalue(FAR struct elf_loadinfo_s *loadinfo, FAR Elf32_Sym *sym,
****************************************************************************/
#ifdef CONFIG_ELF_CONSTRUCTORS
-int elf_findctors(FAR struct elf_loadinfo_s *loadinfo);
+int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo);
#endif
/****************************************************************************
diff --git a/nuttx/binfmt/libelf/libelf_bind.c b/nuttx/binfmt/libelf/libelf_bind.c
index 54ea8f1f0..ef1b4fc8f 100644
--- a/nuttx/binfmt/libelf/libelf_bind.c
+++ b/nuttx/binfmt/libelf/libelf_bind.c
@@ -46,7 +46,6 @@
#include <assert.h>
#include <debug.h>
-#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/elf.h>
#include <nuttx/binfmt/symtab.h>
@@ -247,17 +246,16 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
return ret;
}
- /* Allocate an I/O buffer. This buffer is used only by elf_symname() to
+ /* Allocate an I/O buffer. This buffer is used by elf_symname() to
* accumulate the variable length symbol name.
*/
- loadinfo->iobuffer = (FAR uint8_t *)kmalloc(CONFIG_ELF_BUFFERSIZE);
- if (!loadinfo->iobuffer)
+ ret = elf_allocbuffer(loadinfo);
+ if (ret < 0)
{
- bdbg("Failed to allocate an I/O buffer\n");
+ bdbg("elf_allocbuffer failed: %d\n", ret);
return -ENOMEM;
}
- loadinfo->buflen = CONFIG_ELF_BUFFERSIZE;
/* Process relocations in every allocated section */
@@ -303,11 +301,6 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
arch_flushicache((FAR void*)loadinfo->alloc, loadinfo->allocsize);
#endif
- /* Free the I/O buffer */
-
- kfree(loadinfo->iobuffer);
- loadinfo->iobuffer = NULL;
- loadinfo->buflen = 0;
return ret;
}
diff --git a/nuttx/binfmt/libelf/libelf_ctors.c b/nuttx/binfmt/libelf/libelf_ctors.c
index e8b095bb7..c53923d44 100644
--- a/nuttx/binfmt/libelf/libelf_ctors.c
+++ b/nuttx/binfmt/libelf/libelf_ctors.c
@@ -39,11 +39,15 @@
#include <nuttx/config.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
#include <debug.h>
+#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/elf.h>
-#include "libelf"
+#include "libelf.h"
#ifdef CONFIG_ELF_CONSTRUCTORS
@@ -55,8 +59,6 @@
* Private Types
****************************************************************************/
-typedef FAR void (*ctor_t)(void);
-
/****************************************************************************
* Private Constant Data
****************************************************************************/
@@ -66,9 +68,111 @@ typedef FAR void (*ctor_t)(void);
****************************************************************************/
/****************************************************************************
- * Public Functions
+ * Name: elf_sectname
+ *
+ * Description:
+ * Get the symbol name in loadinfo->iobuffer[].
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
****************************************************************************/
+static inline int elf_sectname(FAR struct elf_loadinfo_s *loadinfo,
+ FAR const Elf32_Shdr *shdr)
+{
+ FAR Elf32_Shdr *shstr;
+ FAR uint8_t *buffer;
+ off_t offset;
+ size_t readlen;
+ size_t bytesread;
+ int shstrndx;
+ int ret;
+
+ /* Get the section header table index of the entry associated with the
+ * section name string table. If the file has no section name string table,
+ * this member holds the value SH_UNDEF.
+ */
+
+ shstrndx = loadinfo->ehdr.e_shstrndx;
+ if (shstrndx == SHN_UNDEF)
+ {
+ bdbg("No section header string table\n");
+ return -EINVAL;
+ }
+
+ /* Get the section name string table section header */
+
+ shstr = &loadinfo->shdr[shstrndx];
+
+ /* Get the file offset to the string that is the name of the section. This
+ * is the sum of:
+ *
+ * shstr->sh_offset: The file offset to the first byte of the section
+ * header string table data.
+ * shdr->sh_name: The offset to the name of the section in the section
+ * name table
+ */
+
+ offset = shstr->sh_offset + shdr->sh_name;
+
+ /* Loop until we get the entire section name into memory */
+
+ buffer = loadinfo->iobuffer;
+ bytesread = 0;
+
+ for (;;)
+ {
+ /* Get the number of bytes to read */
+
+ readlen = loadinfo->buflen - bytesread;
+ if (offset + readlen > loadinfo->filelen)
+ {
+ readlen = loadinfo->filelen - offset;
+ if (readlen <= 0)
+ {
+ bdbg("At end of file\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Read that number of bytes into the array */
+
+ buffer = &loadinfo->iobuffer[bytesread];
+ ret = elf_read(loadinfo, buffer, readlen, offset);
+ if (ret < 0)
+ {
+ bdbg("Failed to read section name\n");
+ return ret;
+ }
+
+ bytesread += readlen;
+
+ /* Did we read the NUL terminator? */
+
+ if (memchr(buffer, '\0', readlen) != NULL)
+ {
+ /* Yes, the buffer contains a NUL terminator. */
+
+ return OK;
+ }
+
+ /* No.. then we have to read more */
+
+ ret = elf_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR);
+ if (ret < 0)
+ {
+ bdbg("elf_reallocbuffer failed: %d\n", ret);
+ return ret;
+ }
+ }
+
+ /* We will not get here */
+
+ return OK;
+}
+
/****************************************************************************
* Name: elf_findctors
*
@@ -79,27 +183,157 @@ typedef FAR void (*ctor_t)(void);
* loadinfo - Load state information
*
* Returned Value:
+ * On success, the index to the CTOR section is returned; A negated errno
+ * value is returned on failure.
+ *
+ ****************************************************************************/
+
+static inline int elf_findctors(FAR struct elf_loadinfo_s *loadinfo)
+{
+ FAR const Elf32_Shdr *shdr;
+ int ret;
+ int i;
+
+ /* Search through the shdr[] array in loadinfo for a section named .ctors */
+
+ for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
+ {
+ /* Get the name of this section */
+
+ shdr = &loadinfo->shdr[i];
+ ret = elf_sectname(loadinfo, shdr);
+ if (ret < 0)
+ {
+ bdbg("elf_sectname failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Check if the name of this section if ".ctors" */
+
+ bvdbg("%d. Comparing \"%s\" and .ctors\"\n", i, loadinfo->iobuffer);
+
+ if (strcmp(".ctors", (FAR const char *)loadinfo->iobuffer) == 0)
+ {
+ /* We found it... return the index */
+
+ return i;
+ }
+ }
+
+ /* We failed to find the .ctors sections. This may not be an error; maybe
+ * there are no static constructors.
+ */
+
+ return -ENOENT;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: elf_loadctors
+ *
+ * Description:
+ * Load points to static constructors into an in-memory array.
+ *
+ * Input Parameters:
+ * loadinfo - Load state information
+ *
+ * Returned Value:
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
-int elf_findctors(FAR struct elf_loadinfo_s *loadinfo)
+int elf_loadctors(FAR struct elf_loadinfo_s *loadinfo)
{
- /* Search through the shdr[] array in loadinfo for a section named .ctors */
-#warning "Missing logic"
+ FAR Elf32_Shdr *shdr;
+ size_t ctorsize;
+ int ctoridx;
+ int ret;
+ int i;
+
+ DEBUGASSERT(loadinfo->ctors == NULL);
+
+ /* Allocate an I/O buffer. This buffer is used by elf_sectname() to
+ * accumulate the variable length symbol name.
+ */
+
+ ret = elf_allocbuffer(loadinfo);
+ if (ret < 0)
+ {
+ bdbg("elf_allocbuffer failed: %d\n", ret);
+ return -ENOMEM;
+ }
+
+ /* Find the index to the section named ".ctors" */
+
+ ctoridx = elf_findctors(loadinfo);
+ if (ctoridx < 0)
+ {
+ /* This may not be a failure. -ENOENT indicates that the file has no
+ * static constructor section.
+ */
- /* Get the address of the beginning of the constructros from the sh_addr
- * field of the section. Save that in the ctors field of the loadinfo
- * structure.
+ bvdbg("elf_findctors failed: %d\n", ctoridx);
+ return ret == -ENOENT ? OK : ret;
+ }
+
+ /* Now we can get a pointer to the .ctor section in the section header
+ * table.
*/
-#warning "Missing logic"
- /* Get the number of constructors from the sh_size field of the section.
- * Save that number in the nctors field of the loadinfo structure.
- */
-#warning "Missing logic"
- return -ENOSYS;
+ shdr = &loadinfo->shdr[ctoridx];
+
+ /* Allocate memory to hold a copy of the .ctor section */
+
+ ctorsize = shdr->sh_size;
+ loadinfo->nctors = ctorsize / sizeof(elf_ctor_t);
+
+ bvdbg("ctoridx=%d ctorsize=%d sizeof(elf_ctor_t)=%d nctors=%d\n",
+ ctoridx, ctorsize, sizeof(elf_ctor_t), loadinfo->nctors);
+
+ /* Check if there are any constructors. It is not an error if there
+ * are none.
+ */
+
+ if (loadinfo->nctors > 0)
+ {
+ /* Check an assumption that we made above */
+
+ DEBUGASSERT(shdr->sh_entsize == sizeof(elf_ctor_t));
+
+ loadinfo->ctors = (elf_ctor_t)kmalloc(ctorsize);
+ if (!loadinfo->ctors)
+ {
+ bdbg("Failed to allocate memory for .ctors\n");
+ return -ENOMEM;
+ }
+
+ /* Read the section header table into memory */
+
+ ret = elf_read(loadinfo, (FAR uint8_t*)loadinfo->ctors, ctorsize,
+ shdr->sh_offset);
+ if (ret < 0)
+ {
+ bdbg("Failed to allocate .ctors: %d\n", ret);
+ }
+
+ /* Fix up all of the .ctor addresses */
+
+ for (i = 0; i < loadinfo->nctors; i++)
+ {
+ FAR uintptr_t *ptr = (uintptr_t *)((FAR void *)(&loadinfo->ctors)[i]);
+
+ bvdbg("ctor %d: %08lx + %08lx = %08lx\n", i,
+ *ptr, loadinfo->alloc, *ptr + loadinfo->alloc);
+
+ *ptr += loadinfo->alloc;
+ }
+ }
+
+ return OK;
}
/****************************************************************************
@@ -119,16 +353,20 @@ int elf_findctors(FAR struct elf_loadinfo_s *loadinfo)
int elf_doctors(FAR struct elf_loadinfo_s *loadinfo)
{
- ctor_t ctor = (ctor_t)loadinfo->ctors;
+ elf_ctor_t ctor = (elf_ctor_t)loadinfo->ctors;
int i;
/* Execute each constructor */
for (i = 0; i < loadinfo->nctors; i++)
{
+ bvdbg("Calling ctor %d at %p\n", i, (FAR void *)ctor);
+
ctor();
ctor++;
}
+
+ return OK;
}
-#endif /* CONFIG_ELF_CONSTRUCTORS
+#endif /* CONFIG_ELF_CONSTRUCTORS */
diff --git a/nuttx/binfmt/libelf/libelf_iobuffer.c b/nuttx/binfmt/libelf/libelf_iobuffer.c
new file mode 100644
index 000000000..ead99ca09
--- /dev/null
+++ b/nuttx/binfmt/libelf/libelf_iobuffer.c
@@ -0,0 +1,136 @@
+/****************************************************************************
+ * binfmt/libelf/elf_iobuffer.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/binfmt/elf.h>
+
+#include "libelf.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: elf_allocbuffer
+ *
+ * Description:
+ * Perform the initial allocation of the I/O buffer, if it has not already
+ * been allocated.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_allocbuffer(FAR struct elf_loadinfo_s *loadinfo)
+{
+ /* Has a buffer been allocated> */
+
+ if (!loadinfo->iobuffer)
+ {
+ /* No.. allocate one now */
+
+ loadinfo->iobuffer = (FAR uint8_t *)kmalloc(CONFIG_ELF_BUFFERSIZE);
+ if (!loadinfo->iobuffer)
+ {
+ bdbg("Failed to allocate an I/O buffer\n");
+ return -ENOMEM;
+ }
+
+ loadinfo->buflen = CONFIG_ELF_BUFFERSIZE;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: elf_reallocbuffer
+ *
+ * Description:
+ * Increase the size of I/O buffer by the specified buffer increment.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_reallocbuffer(FAR struct elf_loadinfo_s *loadinfo, size_t increment)
+{
+ FAR void *buffer;
+ size_t newsize;
+
+ /* Get the new size of the allocation */
+
+ newsize = loadinfo->buflen + increment;
+
+ /* And perform the reallocation */
+
+ buffer = krealloc((FAR void *)loadinfo->iobuffer, newsize);
+ if (!buffer)
+ {
+ bdbg("Failed to reallocate the I/O buffer\n");
+ return -ENOMEM;
+ }
+
+ /* Save the new buffer info */
+
+ loadinfo->iobuffer = buffer;
+ loadinfo->buflen = newsize;
+ return OK;
+}
+
diff --git a/nuttx/binfmt/libelf/libelf_load.c b/nuttx/binfmt/libelf/libelf_load.c
index 6526004f7..505e2c813 100644
--- a/nuttx/binfmt/libelf/libelf_load.c
+++ b/nuttx/binfmt/libelf/libelf_load.c
@@ -126,14 +126,8 @@ static inline int elf_loadshdrs(FAR struct elf_loadinfo_s *loadinfo)
if (ret < 0)
{
bdbg("Failed to read section header table: %d\n", ret);
- goto errout_with_alloc;
}
- return OK;
-
-errout_with_alloc:
- kfree(loadinfo->shdr);
- loadinfo->shdr = 0;
return ret;
}
@@ -233,7 +227,7 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
if (ret < 0)
{
bdbg("Failed to read section %d: %d\n", i, ret);
- goto errout_with_alloc;
+ return ret;
}
}
@@ -248,11 +242,6 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
}
return OK;
-
-errout_with_alloc:
- kfree((FAR void*)loadinfo->alloc);
- loadinfo->alloc = 0;
- return ret;
}
/****************************************************************************
@@ -285,7 +274,7 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
if (ret < 0)
{
bdbg("elf_loadshdrs failed: %d\n", ret);
- return ret;
+ goto errout_with_buffers;
}
/* Determine total size to allocate */
@@ -298,16 +287,17 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
if (ret < 0)
{
bdbg("elf_loadfile failed: %d\n", ret);
- goto errout_with_shdrs;
+ goto errout_with_buffers;
}
/* Find static constructors. */
#ifdef CONFIG_ELF_CONSTRUCTORS
- ret = elf_findctors(loadinfo);
+ ret = elf_loadctors(loadinfo);
+ if (ret < 0)
{
- bdbg("elf_findctors failed: %d\n", ret);
- goto errout_with_shdrs;
+ bdbg("elf_loadctors failed: %d\n", ret);
+ goto errout_with_buffers;
}
#endif
@@ -315,9 +305,8 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
/* Error exits */
-errout_with_shdrs:
- kfree(loadinfo->shdr);
- loadinfo->shdr = NULL;
+errout_with_buffers:
+ elf_freebuffers(loadinfo);
return ret;
}
diff --git a/nuttx/binfmt/libelf/libelf_symbols.c b/nuttx/binfmt/libelf/libelf_symbols.c
index 123f9f77f..2d94b11af 100644
--- a/nuttx/binfmt/libelf/libelf_symbols.c
+++ b/nuttx/binfmt/libelf/libelf_symbols.c
@@ -101,7 +101,6 @@ static int elf_symname(FAR struct elf_loadinfo_s *loadinfo,
/* Loop until we get the entire symbol name into memory */
- buffer = loadinfo->iobuffer;
bytesread = 0;
for (;;)
@@ -125,7 +124,7 @@ static int elf_symname(FAR struct elf_loadinfo_s *loadinfo,
ret = elf_read(loadinfo, buffer, readlen, offset);
if (ret < 0)
{
- bdbg("Failed to read symbol name\n");
+ bdbg("elf_read failed: %d\n", ret);
return ret;
}
@@ -142,18 +141,12 @@ static int elf_symname(FAR struct elf_loadinfo_s *loadinfo,
/* No.. then we have to read more */
- buffer = realloc((FAR void *)loadinfo->iobuffer,
- loadinfo->buflen + CONFIG_ELF_BUFFERINCR);
- if (!buffer)
+ ret = elf_reallocbuffer(loadinfo, CONFIG_ELF_BUFFERINCR);
+ if (ret < 0)
{
- bdbg("Failed to reallocate the I/O buffer\n");
- return -ENOMEM;
+ bdbg("elf_reallocbuffer failed: %d\n", ret);
+ return ret;
}
-
- /* Save the new buffer info */
-
- loadinfo->iobuffer = buffer;
- loadinfo->buflen += CONFIG_ELF_BUFFERINCR;
}
/* We will not get here */
diff --git a/nuttx/binfmt/libelf/libelf_uninit.c b/nuttx/binfmt/libelf/libelf_uninit.c
index e5fa2e6c3..06bb89681 100644
--- a/nuttx/binfmt/libelf/libelf_uninit.c
+++ b/nuttx/binfmt/libelf/libelf_uninit.c
@@ -42,8 +42,12 @@
#include <unistd.h>
#include <debug.h>
#include <errno.h>
+
+#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/elf.h>
+#include "libelf.h"
+
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
@@ -75,6 +79,12 @@
int elf_uninit(struct elf_loadinfo_s *loadinfo)
{
+ /* Free all working buffers */
+
+ elf_freebuffers(loadinfo);
+
+ /* Close the ELF file */
+
if (loadinfo->filfd >= 0)
{
close(loadinfo->filfd);
@@ -83,3 +93,43 @@ int elf_uninit(struct elf_loadinfo_s *loadinfo)
return OK;
}
+/****************************************************************************
+ * Name: elf_freebuffers
+ *
+ * Description:
+ * Release all working buffers.
+ *
+ * Returned Value:
+ * 0 (OK) is returned on success and a negated errno is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int elf_freebuffers(struct elf_loadinfo_s *loadinfo)
+{
+ /* Release all working allocations */
+
+ if (loadinfo->shdr)
+ {
+ kfree((FAR void *)loadinfo->shdr);
+ loadinfo->shdr = NULL;
+ }
+
+#ifdef CONFIG_ELF_CONSTRUCTORS
+ if (loadinfo->ctors)
+ {
+ kfree((FAR void *)loadinfo->ctors);
+ loadinfo->ctors = NULL;
+ loadinfo->nctors = 0;
+ }
+#endif
+
+ if (loadinfo->iobuffer)
+ {
+ kfree((FAR void *)loadinfo->iobuffer);
+ loadinfo->iobuffer = NULL;
+ loadinfo->buflen = 0;
+ }
+
+ return OK;
+}
diff --git a/nuttx/binfmt/libelf/libelf_unload.c b/nuttx/binfmt/libelf/libelf_unload.c
index 335106407..d7a882711 100644
--- a/nuttx/binfmt/libelf/libelf_unload.c
+++ b/nuttx/binfmt/libelf/libelf_unload.c
@@ -45,6 +45,8 @@
#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/elf.h>
+#include "libelf.h"
+
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
@@ -76,7 +78,11 @@
int elf_unload(struct elf_loadinfo_s *loadinfo)
{
- /* Release the all allocated memory */
+ /* Free all working buffers */
+
+ elf_freebuffers(loadinfo);
+
+ /* Release memory holding the relocated ELF image */
if (loadinfo->alloc)
{
@@ -85,19 +91,6 @@ int elf_unload(struct elf_loadinfo_s *loadinfo)
loadinfo->allocsize = 0;
}
- if (loadinfo->shdr)
- {
- kfree((FAR void *)loadinfo->shdr);
- loadinfo->shdr = NULL;
- }
-
- if (loadinfo->iobuffer)
- {
- kfree((FAR void *)loadinfo->iobuffer);
- loadinfo->iobuffer = NULL;
- loadinfo->buflen = 0;
- }
-
return OK;
}
diff --git a/nuttx/configs/stm32f4discovery/elf/Make.defs b/nuttx/configs/stm32f4discovery/elf/Make.defs
index c64102d17..7df9b13da 100644
--- a/nuttx/configs/stm32f4discovery/elf/Make.defs
+++ b/nuttx/configs/stm32f4discovery/elf/Make.defs
@@ -161,6 +161,8 @@ LDNXFLATFLAGS = -e main -s 2048
# ELF module definitions
CELFFLAGS = $(CFLAGS) -mlong-calls
+CXXELFFLAGS = $(CXXFLAGS) -mlong-calls
+
LDELFFLAGS = -r -e main
ifeq ($(WINTOOL),y)
LDELFFLAGS += -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/gnu-elf.ld}"
diff --git a/nuttx/configs/stm32f4discovery/elf/defconfig b/nuttx/configs/stm32f4discovery/elf/defconfig
index 5bbef5e73..59c221a0c 100644
--- a/nuttx/configs/stm32f4discovery/elf/defconfig
+++ b/nuttx/configs/stm32f4discovery/elf/defconfig
@@ -28,6 +28,7 @@ CONFIG_INTELHEX_BINARY=y
#
# CONFIG_ARCH_STDBOOL_H is not set
# CONFIG_ARCH_MATH_H is not set
+# CONFIG_ARCH_FLOAT_H is not set
# CONFIG_ARCH_STDARG_H is not set
#
@@ -387,7 +388,7 @@ CONFIG_ELF_ALIGN_LOG2=2
CONFIG_ELF_STACKSIZE=2048
CONFIG_ELF_BUFFERSIZE=128
CONFIG_ELF_BUFFERINCR=32
-# CONFIG_ELF_CONSTRUCTORS is not set
+CONFIG_ELF_CONSTRUCTORS=y
CONFIG_SYMTAB_ORDEREDBYNAME=y
#
@@ -397,6 +398,7 @@ CONFIG_STDIO_BUFFER_SIZE=256
CONFIG_STDIO_LINEBUFFER=y
CONFIG_NUNGET_CHARS=2
CONFIG_LIB_HOMEDIR="/"
+# CONFIG_LIBM is not set
# CONFIG_NOPRINTF_FIELDWIDTH is not set
# CONFIG_LIBC_FLOATINGPOINT is not set
# CONFIG_EOL_IS_CR is not set
@@ -425,265 +427,58 @@ CONFIG_HAVE_CXX=y
#
# Examples
#
-
-#
-# ADC Example
-#
-
-#
-# Buttons Example
-#
# CONFIG_EXAMPLES_BUTTONS is not set
-
-#
-# CAN Example
-#
# CONFIG_EXAMPLES_CAN is not set
-
-#
-# USB CDC/ACM Class Driver Example
-#
# CONFIG_EXAMPLES_CDCACM is not set
-
-#
-# USB composite Class Driver Example
-#
# CONFIG_EXAMPLES_COMPOSITE is not set
-
-#
-# DHCP Server Example
-#
# CONFIG_EXAMPLES_DHCPD is not set
-
-#
-# ELF Loader Example
-#
CONFIG_EXAMPLES_ELF=y
CONFIG_EXAMPLES_ELF_DEVMINOR=0
CONFIG_EXAMPLES_ELF_DEVPATH="/dev/ram0"
-
-#
-# FTP Client Example
-#
# CONFIG_EXAMPLES_FTPC is not set
-
-#
-# FTP Server Example
-#
# CONFIG_EXAMPLES_FTPD is not set
-
-#
-# "Hello, World!" Example
-#
# CONFIG_EXAMPLES_HELLO is not set
-
-#
-# "Hello, World!" C++ Example
-#
# CONFIG_EXAMPLES_HELLOXX is not set
-
-#
-# USB HID Keyboard Example
-#
+# CONFIG_EXAMPLES_JSON is not set
# CONFIG_EXAMPLES_HIDKBD is not set
-
-#
-# IGMP Example
-#
# CONFIG_EXAMPLES_IGMP is not set
-
-#
-# LCD Read/Write Example
-#
# CONFIG_EXAMPLES_LCDRW is not set
-
-#
-# Memory Management Example
-#
# CONFIG_EXAMPLES_MM is not set
-
-#
-# File System Mount Example
-#
# CONFIG_EXAMPLES_MOUNT is not set
-
-#
-# FreeModBus Example
-#
# CONFIG_EXAMPLES_MODBUS is not set
-
-#
-# Network Test Example
-#
# CONFIG_EXAMPLES_NETTEST is not set
-
-#
-# NuttShell (NSH) Example
-#
# CONFIG_EXAMPLES_NSH is not set
-
-#
-# NULL Example
-#
# CONFIG_EXAMPLES_NULL is not set
-
-#
-# NX Graphics Example
-#
# CONFIG_EXAMPLES_NX is not set
-
-#
-# NxConsole Example
-#
# CONFIG_EXAMPLES_NXCONSOLE is not set
-
-#
-# NXFFS File System Example
-#
# CONFIG_EXAMPLES_NXFFS is not set
-
-#
-# NXFLAT Example
-#
# CONFIG_EXAMPLES_NXFLAT is not set
-
-#
-# NX Graphics "Hello, World!" Example
-#
# CONFIG_EXAMPLES_NXHELLO is not set
-
-#
-# NX Graphics image Example
-#
# CONFIG_EXAMPLES_NXIMAGE is not set
-
-#
-# NX Graphics lines Example
-#
# CONFIG_EXAMPLES_NXLINES is not set
-
-#
-# NX Graphics Text Example
-#
# CONFIG_EXAMPLES_NXTEXT is not set
-
-#
-# OS Test Example
-#
# CONFIG_EXAMPLES_OSTEST is not set
-
-#
-# Pascal "Hello, World!"example
-#
# CONFIG_EXAMPLES_PASHELLO is not set
-
-#
-# Pipe Example
-#
# CONFIG_EXAMPLES_PIPE is not set
-
-#
-# Poll Example
-#
# CONFIG_EXAMPLES_POLL is not set
-
-#
-# Pulse Width Modulation (PWM) Example
-#
-
-#
-# Quadrature Encoder Example
-#
# CONFIG_EXAMPLES_QENCODER is not set
-
-#
-# RGMP Example
-#
# CONFIG_EXAMPLES_RGMP is not set
-
-#
-# ROMFS Example
-#
# CONFIG_EXAMPLES_ROMFS is not set
-
-#
-# sendmail Example
-#
# CONFIG_EXAMPLES_SENDMAIL is not set
-
-#
-# Serial Loopback Example
-#
# CONFIG_EXAMPLES_SERLOOP is not set
-
-#
-# Telnet Daemon Example
-#
# CONFIG_EXAMPLES_TELNETD is not set
-
-#
-# THTTPD Web Server Example
-#
# CONFIG_EXAMPLES_THTTPD is not set
-
-#
-# TIFF Generation Example
-#
# CONFIG_EXAMPLES_TIFF is not set
-
-#
-# Touchscreen Example
-#
# CONFIG_EXAMPLES_TOUCHSCREEN is not set
-
-#
-# UDP Example
-#
# CONFIG_EXAMPLES_UDP is not set
-
-#
-# UDP Discovery Daemon Example
-#
-
-#
-# uIP Web Server Example
-#
# CONFIG_EXAMPLES_UIP is not set
-
-#
-# USB Serial Test Example
-#
# CONFIG_EXAMPLES_USBSERIAL is not set
-
-#
-# USB Mass Storage Class Example
-#
# CONFIG_EXAMPLES_USBMSC is not set
-
-#
-# USB Serial Terminal Example
-#
# CONFIG_EXAMPLES_USBTERM is not set
-
-#
-# Watchdog timer Example
-#
# CONFIG_EXAMPLES_WATCHDOG is not set
-
-#
-# wget Example
-#
-
-#
-# WLAN Example
-#
# CONFIG_EXAMPLES_WLAN is not set
#
-# XML RPC Example
-#
-
-#
# Interpreters
#
@@ -700,75 +495,20 @@ CONFIG_EXAMPLES_ELF_DEVPATH="/dev/ram0"
#
# Networking Utilities
#
-
-#
-# DHCP client
-#
# CONFIG_NETUTILS_DHCPC is not set
-
-#
-# DHCP server
-#
# CONFIG_NETUTILS_DHCPD is not set
-
-#
-# FTP client
-#
# CONFIG_NETUTILS_FTPC is not set
-
-#
-# FTP server
-#
# CONFIG_NETUTILS_FTPD is not set
-
-#
-# Name resolution
-#
+# CONFIG_NETUTILS_JSON is not set
# CONFIG_NETUTILS_RESOLV is not set
-
-#
-# SMTP
-#
# CONFIG_NETUTILS_SMTP is not set
-
-#
-# TFTP client
-#
# CONFIG_NETUTILS_TELNETD is not set
-
-#
-# TFTP client
-#
# CONFIG_NETUTILS_TFTPC is not set
-
-#
-# THTTPD web server
-#
# CONFIG_NETUTILS_THTTPD is not set
-
-#
-# uIP support library
-#
# CONFIG_NETUTILS_UIPLIB is not set
-
-#
-# uIP web client
-#
# CONFIG_NETUTILS_WEBCLIENT is not set
#
-# uIP web server
-#
-
-#
-# UDP Discovery Utility
-#
-
-#
-# XML-RPC library
-#
-
-#
# ModBus
#
diff --git a/nuttx/include/nuttx/binfmt/elf.h b/nuttx/include/nuttx/binfmt/elf.h
index aa04adaf2..4770d82a3 100644
--- a/nuttx/include/nuttx/binfmt/elf.h
+++ b/nuttx/include/nuttx/binfmt/elf.h
@@ -59,6 +59,9 @@
/****************************************************************************
* Public Types
****************************************************************************/
+/* The type of one C++ constructor */
+
+typedef FAR void (*elf_ctor_t)(void);
/* This struct provides a desciption of the currently loaded instantiation
* of an ELF binary.
@@ -71,7 +74,7 @@ struct elf_loadinfo_s
off_t filelen; /* Length of the entire ELF file */
int filfd; /* Descriptor for the file being loaded */
#ifdef CONFIG_ELF_CONSTRUCTORS
- uintptr_t ctors; /* Location of static constructors in memory */
+ elf_ctor_t ctors; /* Pointer to a list of constructors */
uint16_t nctors; /* Number of constructors */
#endif
uint16_t symtabidx; /* Symbol table section index */