diff options
author | Chris Johns <chrisj@rtems.org> | 2013-01-12 07:43:42 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2013-01-12 07:43:42 +1100 |
commit | 76172ffa93a1205c82e0fb3aa4bc69788240a981 (patch) | |
tree | 6e5252c16a06b3f1f8423b6befeb06bc1a08b380 | |
parent | bade51b70fa86b067f8f6a1cb4df5ff62e6d4b67 (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.c | 14 | ||||
-rw-r--r-- | rtl-elf.h | 7 | ||||
-rw-r--r-- | rtl-find-file.c | 113 | ||||
-rw-r--r-- | rtl-find-file.h | 45 | ||||
-rw-r--r-- | rtl-obj.c | 82 | ||||
-rw-r--r-- | rtl-obj.h | 43 | ||||
-rw-r--r-- | rtl-rap.c | 17 | ||||
-rw-r--r-- | rtl-rap.h | 7 | ||||
-rw-r--r-- | wscript | 1 |
9 files changed, 248 insertions, 81 deletions
@@ -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; +} @@ -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 @@ -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; } @@ -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; /** @@ -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; +} @@ -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 */ @@ -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', |