From 76172ffa93a1205c82e0fb3aa4bc69788240a981 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Sat, 12 Jan 2013 07:43:42 +1100 Subject: 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. --- rtl-elf.c | 14 +++++++ rtl-elf.h | 7 ++++ rtl-find-file.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rtl-find-file.h | 45 ++++++++++++++++++++++ rtl-obj.c | 82 ++++------------------------------------ rtl-obj.h | 43 ++++++++++++++++++--- rtl-rap.c | 17 ++++++++- rtl-rap.h | 7 ++++ wscript | 1 + 9 files changed, 248 insertions(+), 81 deletions(-) create mode 100644 rtl-find-file.c create mode 100644 rtl-find-file.h 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 + * + * 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 +#include +#include +#include +#include +#include + +#include + +#include +#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 + * + * 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 +#include + +#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 -#include #include #include #include -#include #include @@ -30,13 +28,10 @@ #include #include #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 #include @@ -25,25 +25,56 @@ 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 + * COPYRIGHT (c) 2012-2013 Chris Johns * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -41,6 +41,15 @@ #define REL_R_INFO (1) #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. */ @@ -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', -- cgit v1.2.3