summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2013-01-12 07:43:42 +1100
committerChris Johns <chrisj@rtems.org>2013-01-12 07:43:42 +1100
commit76172ffa93a1205c82e0fb3aa4bc69788240a981 (patch)
tree6e5252c16a06b3f1f8423b6befeb06bc1a08b380
parentbade51b70fa86b067f8f6a1cb4df5ff62e6d4b67 (diff)
Add format signatures. Add find files.
Add a format signature so loaded files can be managed by format type. Move the find file code to a common routine to allow reuse.
-rw-r--r--rtl-elf.c14
-rw-r--r--rtl-elf.h7
-rw-r--r--rtl-find-file.c113
-rw-r--r--rtl-find-file.h45
-rw-r--r--rtl-obj.c82
-rw-r--r--rtl-obj.h43
-rw-r--r--rtl-rap.c17
-rw-r--r--rtl-rap.h7
-rw-r--r--wscript1
9 files changed, 248 insertions, 81 deletions
diff --git a/rtl-elf.c b/rtl-elf.c
index d1d97dc..fb2a9ae 100644
--- a/rtl-elf.c
+++ b/rtl-elf.c
@@ -39,6 +39,15 @@
#define REL_R_INFO (1)
#define REL_R_ADDEND (2)
+/**
+ * The ELF format signature.
+ */
+static rtems_rtl_loader_format_t elf_sig =
+{
+ .label = "ELF",
+ .flags = RTEMS_RTL_FMT_ELF
+};
+
static bool
rtems_rtl_elf_machine_check (Elf_Ehdr* ehdr)
{
@@ -761,3 +770,8 @@ rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd)
return true;
}
+rtems_rtl_loader_format_t*
+rtems_rtl_elf_file_sig (void)
+{
+ return &elf_sig;
+}
diff --git a/rtl-elf.h b/rtl-elf.h
index 470187b..24bb5ba 100644
--- a/rtl-elf.h
+++ b/rtl-elf.h
@@ -144,6 +144,13 @@ bool rtems_rtl_elf_file_check (rtems_rtl_obj_t* obj, int fd);
*/
bool rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd);
+/**
+ * The ELF format signature handler.
+ *
+ * @return rtems_rtl_loader_format_t* The format's signature.
+ */
+rtems_rtl_loader_format_t* rtems_rtl_elf_file_sig (void);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/rtl-find-file.c b/rtl-find-file.c
new file mode 100644
index 0000000..87a7501
--- /dev/null
+++ b/rtl-find-file.c
@@ -0,0 +1,113 @@
+/*
+ * COPYRIGHT (c) 2012-2013 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtl
+ *
+ * @brief RTEMS Run-Time Linker Error
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rtems/libio_.h>
+
+#include <rtl.h>
+#include "rtl-find-file.h"
+#include "rtl-error.h"
+#include "rtl-string.h"
+#include "rtl-trace.h"
+
+#if WAF_BUILD
+#define rtems_filesystem_is_delimiter rtems_filesystem_is_separator
+#endif
+
+bool
+rtems_rtl_find_file (const char* name,
+ const char* paths,
+ const char** file_name,
+ uint32_t* size)
+{
+ struct stat sb;
+
+ *file_name = NULL;
+ *size = 0;
+
+ if (rtems_filesystem_is_delimiter (name[0]))
+ {
+ if (stat (name, &sb) == 0)
+ *file_name = rtems_rtl_strdup (name);
+ }
+ else
+ {
+ const char* start;
+ const char* end;
+ int len;
+ char* fname;
+
+ start = paths;
+ end = start + strlen (paths);
+ len = strlen (name);
+
+ while (!*file_name && (start != end))
+ {
+ const char* delimiter = strchr (start, ':');
+
+ if (delimiter == NULL)
+ delimiter = end;
+
+ /*
+ * Allocate the path fragment, separator, name, terminating nul. Form the
+ * path then see if the stat call works.
+ */
+
+ fname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+ (delimiter - start) + 1 + len + 1, true);
+ if (!fname)
+ {
+ rtems_rtl_set_error (ENOMEM, "no memory searching for file");
+ return false;
+ }
+
+ memcpy (fname, start, delimiter - start);
+ fname[delimiter - start] = '/';
+ memcpy (fname + (delimiter - start) + 1, name, len);
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
+ printf ("rtl: find-file: path: %s\n", fname);
+
+ if (stat (fname, &sb) < 0)
+ rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, fname);
+ else
+ *file_name = fname;
+
+ start = delimiter;
+ if (start != end)
+ ++start;
+ }
+ }
+
+ if (!*file_name)
+ {
+ rtems_rtl_set_error (ENOMEM, "file not found");
+ return false;
+ }
+
+ *size = sb.st_size;
+
+ return true;
+}
diff --git a/rtl-find-file.h b/rtl-find-file.h
new file mode 100644
index 0000000..0daa7bf
--- /dev/null
+++ b/rtl-find-file.h
@@ -0,0 +1,45 @@
+/*
+ * COPYRIGHT (c) 2012-2013 Chris Johns <chrisj@rtems.org>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object Support.
+ */
+
+#if !defined (_RTEMS_RTL_FIND_FILE_H_)
+#define _RTEMS_RTL_FIND_FILE_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Find a file on disk given a name and a path.
+ *
+ * @param name The file name to find. Can be relative or absolute.
+ * @param paths The paths to search.
+ * @param file_name Place the full path in this location if found.
+ * @param size The size of the file if found as returned by the 'stat' call.
+ * @retval true The file was found.
+ * @retval false The file was not found.
+ */
+bool rtems_rtl_find_file (const char* name,
+ const char* paths,
+ const char** file_name,
+ uint32_t* size);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/rtl-obj.c b/rtl-obj.c
index b5696ad..df7ec8b 100644
--- a/rtl-obj.c
+++ b/rtl-obj.c
@@ -18,11 +18,9 @@
#endif
#include <errno.h>
-#include <fcntl.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
-#include <unistd.h>
#include <rtems/libio_.h>
@@ -30,13 +28,10 @@
#include <rtl-chain-iterator.h>
#include <rtl-obj.h>
#include "rtl-error.h"
+#include "rtl-find-file.h"
#include "rtl-string.h"
#include "rtl-trace.h"
-#if WAF_BUILD
-#define rtems_filesystem_is_delimiter rtems_filesystem_is_separator
-#endif
-
#if RTEMS_RTL_RAP_LOADER
#include "rtl-rap.h"
#define RTEMS_RTL_RAP_LOADER_COUNT 1
@@ -58,10 +53,10 @@ static rtems_rtl_loader_table_t loaders[RTEMS_RTL_ELF_LOADER_COUNT +
RTEMS_RTL_RAP_LOADER_COUNT] =
{
#if RTEMS_RTL_RAP_LOADER
- { rtems_rtl_rap_file_check, rtems_rtl_rap_file_load },
+ { rtems_rtl_rap_file_check, rtems_rtl_rap_file_load, rtems_rtl_rap_file_sig },
#endif
#if RTEMS_RTL_ELF_LOADER
- { rtems_rtl_elf_file_check, rtems_rtl_elf_file_load },
+ { rtems_rtl_elf_file_check, rtems_rtl_elf_file_load, rtems_rtl_elf_file_sig },
#endif
};
@@ -346,8 +341,8 @@ rtems_rtl_match_name (rtems_rtl_obj_t* obj, const char* name)
bool
rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name)
{
- struct stat sb;
- const char* pname;
+ const char* pname;
+ rtems_rtl_data_t* rtl;
/*
* Parse the name. The object descriptor will have the archive name and/or
@@ -369,73 +364,12 @@ rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name)
else
pname = rtems_rtl_obj_oname (obj);
- if (rtems_filesystem_is_delimiter (pname[0]))
- {
- if (stat (pname, &sb) == 0)
- obj->fname = rtems_rtl_strdup (pname);
- }
- else
- {
- rtems_rtl_data_t* rtl;
- const char* start;
- const char* end;
- int len;
- char* fname;
-
- rtl = rtems_rtl_lock ();
-
- start = rtl->paths;
- end = start + strlen (rtl->paths);
- len = strlen (pname);
-
- while (!obj->fname && (start != end))
- {
- const char* delimiter = strchr (start, ':');
-
- if (delimiter == NULL)
- delimiter = end;
-
- /*
- * Allocate the path fragment, separator, name, terminating nul. Form the
- * path then see if the stat call works.
- */
-
- fname = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
- (delimiter - start) + 1 + len + 1, true);
- if (!fname)
- {
- rtems_rtl_set_error (ENOMEM, "no memory searching for object file");
- rtems_rtl_unlock ();
- return false;
- }
-
- memcpy (fname, start, delimiter - start);
- fname[delimiter - start] = '/';
- memcpy (fname + (delimiter - start) + 1, pname, len);
-
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD))
- printf ("rtl: loading: find-path: %s\n", fname);
-
- if (stat (fname, &sb) < 0)
- rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, fname);
- else
- obj->fname = fname;
-
- start = delimiter;
- if (start != end)
- ++start;
- }
+ rtl = rtems_rtl_lock ();
- rtems_rtl_unlock ();
- }
-
- if (!obj->fname)
- {
- rtems_rtl_set_error (ENOMEM, "object file not found");
+ if (!rtems_rtl_find_file (pname, rtl->paths, &obj->fname, &obj->fsize))
return false;
- }
- obj->fsize = sb.st_size;
+ rtems_rtl_unlock ();
return true;
}
diff --git a/rtl-obj.h b/rtl-obj.h
index 8df042f..5396a6c 100644
--- a/rtl-obj.h
+++ b/rtl-obj.h
@@ -13,8 +13,8 @@
* @brief RTEMS Run-Time Linker Object Support.
*/
-#if !defined (_RTEMS_RTL_MAP_H_)
-#define _RTEMS_RTL_MAP_H_
+#if !defined (_RTEMS_RTL_OBJ_H_)
+#define _RTEMS_RTL_OBJ_H_
#include <rtems.h>
#include <rtems/chain.h>
@@ -26,24 +26,55 @@ extern "C" {
#endif /* __cplusplus */
/**
+ * Loader format flags.
+ */
+#define RTEMS_RTL_FMT_ELF (1 << 0)
+#define RTEMS_RTL_FMT_COMP (1 << 1)
+#define RTEMS_RTL_FMT_PRIVATE (1 << 16)
+
+/**
+ * Loader format definition.
+ */
+typedef struct rtems_rtl_loader_format_s
+{
+ /**
+ * The format label. This can be used to determine and manage
+ * specific formats.
+ */
+ const char* label;
+
+ /**
+ * The format flags.
+ */
+ uint32_t flags;
+} rtems_rtl_loader_format_t;
+
+/**
* The type of the format loader check handler. This handler checks the format
* and if it is detected as suitable it returns true.
*/
-typedef bool (*rtems_rtl_loader_check)(rtems_rtl_obj_t* obj, int fd);
+typedef bool (*rtems_rtl_loader_check) (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The type of the format loader handler. This handler loads the specific
+ * format.
+ */
+typedef bool (*rtems_rtl_loader_load) (rtems_rtl_obj_t* obj, int fd);
/**
* The type of the format loader handler. This handler loads the specific
* format.
*/
-typedef bool (*rtems_rtl_loader_load)(rtems_rtl_obj_t* obj, int fd);
+typedef rtems_rtl_loader_format_t* (*rtems_rtl_loader_sig) (void);
/**
* Table for supported loadable formats.
*/
typedef struct rtems_rtl_loader_table_s
{
- rtems_rtl_loader_check check; /**< The check handler. */
- rtems_rtl_loader_load load; /**< The loader. */
+ rtems_rtl_loader_check check; /**< The check handler. */
+ rtems_rtl_loader_load load; /**< The loader. */
+ rtems_rtl_loader_sig signature; /**< The loader's signature. */
} rtems_rtl_loader_table_t;
/**
diff --git a/rtl-rap.c b/rtl-rap.c
index 6b3dd9d..efe2362 100644
--- a/rtl-rap.c
+++ b/rtl-rap.c
@@ -1,5 +1,5 @@
/*
- * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ * COPYRIGHT (c) 2012-2013 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -42,6 +42,15 @@
#define REL_R_ADDEND (2)
/**
+ * The ELF format signature.
+ */
+static rtems_rtl_loader_format_t rap_sig =
+{
+ .label = "RAP",
+ .flags = RTEMS_RTL_FMT_COMP
+};
+
+/**
* The section definitions found in a RAP file.
*/
typedef struct rtems_rtl_rap_sectdef_s
@@ -794,3 +803,9 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd)
return true;
}
+
+rtems_rtl_loader_format_t*
+rtems_rtl_rap_file_sig (void)
+{
+ return &rap_sig;
+}
diff --git a/rtl-rap.h b/rtl-rap.h
index d937018..12cc95a 100644
--- a/rtl-rap.h
+++ b/rtl-rap.h
@@ -40,6 +40,13 @@ bool rtems_rtl_rap_file_check (rtems_rtl_obj_t* obj, int fd);
*/
bool rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd);
+/**
+ * The RAP format signature handler.
+ *
+ * @return rtems_rtl_loader_format_t* The format's signature.
+ */
+rtems_rtl_loader_format_t* rtems_rtl_rap_file_sig (void);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/wscript b/wscript
index c0ed980..2faba1b 100644
--- a/wscript
+++ b/wscript
@@ -92,6 +92,7 @@ def build(bld):
'rtl-debugger.c',
'rtl-elf.c',
'rtl-error.c',
+ 'rtl-find-file.c',
'rtl-obj.c',
'rtl-obj-cache.c',
'rtl-obj-comp.c',