diff options
Diffstat (limited to 'cpukit')
-rw-r--r-- | cpukit/libdl/rtl-obj-cache.c | 87 | ||||
-rw-r--r-- | cpukit/libdl/rtl-trace.c | 4 | ||||
-rw-r--r-- | cpukit/libdl/rtl-trace.h | 25 |
3 files changed, 86 insertions, 30 deletions
diff --git a/cpukit/libdl/rtl-obj-cache.c b/cpukit/libdl/rtl-obj-cache.c index 9221765142..a4676cfa0d 100644 --- a/cpukit/libdl/rtl-obj-cache.c +++ b/cpukit/libdl/rtl-obj-cache.c @@ -19,12 +19,14 @@ #endif #include <errno.h> +#include <stdio.h> #include <string.h> #include <unistd.h> #include <rtems/rtl/rtl-allocator.h> #include "rtl-obj-cache.h" #include "rtl-error.h" +#include "rtl-trace.h" bool rtems_rtl_obj_cache_open (rtems_rtl_obj_cache_t* cache, size_t size) @@ -46,7 +48,10 @@ rtems_rtl_obj_cache_open (rtems_rtl_obj_cache_t* cache, size_t size) void rtems_rtl_obj_cache_close (rtems_rtl_obj_cache_t* cache) { + if (rtems_rtl_trace (RTEMS_RTL_TRACE_CACHE)) + printf ("rtl: cache: %2d: close\n", cache->fd); rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, cache->buffer); + cache->buffer = NULL; cache->fd = -1; cache->file_size = 0; cache->level = 0; @@ -55,8 +60,11 @@ rtems_rtl_obj_cache_close (rtems_rtl_obj_cache_t* cache) void rtems_rtl_obj_cache_flush (rtems_rtl_obj_cache_t* cache) { + if (rtems_rtl_trace (RTEMS_RTL_TRACE_CACHE)) + printf ("rtl: cache: %2d: flush\n", cache->fd); cache->fd = -1; cache->file_size = 0; + cache->offset = 0; cache->level = 0; } @@ -69,6 +77,13 @@ rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache, { struct stat sb; + if (rtems_rtl_trace (RTEMS_RTL_TRACE_CACHE)) + printf ("rtl: cache: %2d: fd=%d offset=%d length=%d area=[%d,%d] cache=[%d,%d] size=%d\n", + fd, cache->fd, (int) offset, (int) *length, + (int) offset, (int) offset + *length, + (int) cache->offset, (int) cache->offset + cache->level, + (int) cache->file_size); + if (*length > cache->size) { rtems_rtl_set_error (EINVAL, "read size larger than cache size"); @@ -84,8 +99,15 @@ rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache, return false; } + /* + * We sometimes are asked to read strings of a length we do not know. + */ if ((offset + *length) > cache->file_size) + { *length = cache->file_size - offset; + if (rtems_rtl_trace (RTEMS_RTL_TRACE_CACHE)) + printf ("rtl: cache: %2d: truncate length=%d\n", fd, (int) *length); + } } while (true) @@ -99,12 +121,21 @@ rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache, if (fd == cache->fd) { /* + * Do not read past the end of the file. + */ + if ((offset + buffer_read) > cache->file_size) + buffer_read = cache->file_size - offset; + + /* * Is any part of the data in the cache ? */ if ((offset >= cache->offset) && (offset < (cache->offset + cache->level))) { + size_t size; + buffer_offset = offset - cache->offset; + size = cache->level - buffer_offset; /* * Return the location of the data in the cache. @@ -114,24 +145,38 @@ rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache, /* * Is all the data in the cache or just a part ? */ - if (*length <= (cache->level - buffer_offset)) - { + if (*length <= size) return true; - } + + if (rtems_rtl_trace (RTEMS_RTL_TRACE_CACHE)) + printf ("rtl: cache: %2d: copy-down: buffer_offset=%d size=%d level=%d\n", + fd, (int) buffer_offset, (int) size, (int) cache->level); /* - * Copy down the data in the buffer and then fill the remaining - * space with as much data we are able to read. + * Copy down the data in the buffer and then fill the remaining space + * with as much data we are able to read. */ - memmove (cache->buffer, - cache->buffer + buffer_offset, - cache->size - buffer_offset); + memmove (cache->buffer, cache->buffer + buffer_offset, size); + + cache->offset = offset; + cache->level = size; + buffer_read = cache->size - cache->level; + buffer_offset = size; - buffer_read = buffer_offset; - buffer_offset = cache->size - buffer_offset; + /* + * Do not read past the end of the file. + */ + if ((offset + buffer_offset + buffer_read) > cache->file_size) + buffer_read = cache->file_size - (offset + buffer_offset); } } + if (rtems_rtl_trace (RTEMS_RTL_TRACE_CACHE)) + printf ("rtl: cache: %2d: seek: offset=%d buffer_offset=%d read=%d cache=[%d,%d] dist=%d\n", + fd, (int) offset + buffer_offset, (int) buffer_offset, (int) buffer_read, + (int) offset, (int) offset + buffer_read, + (int) (cache->file_size - offset)); + if (lseek (fd, offset + buffer_offset, SEEK_SET) < 0) { rtems_rtl_set_error (errno, "file seek failed"); @@ -143,7 +188,9 @@ rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache, * returned and if data has been read check if the amount is what we * want. If not it is an error. A POSIX read can read data in fragments. */ - cache->level = buffer_read; + + cache->level = buffer_offset + buffer_read; + while (buffer_read) { int r = read (fd, cache->buffer + buffer_offset, buffer_read); @@ -154,6 +201,8 @@ rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache, } if ((r == 0) && buffer_read) { + if (rtems_rtl_trace (RTEMS_RTL_TRACE_CACHE)) + printf ("rtl: cache: %2d: read: past end by=%d\n", fd, (int) buffer_read); cache->level = cache->level - buffer_read; buffer_read = 0; } @@ -164,16 +213,20 @@ rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache, } } - cache->fd = fd; cache->offset = offset; - if (fstat (cache->fd, &sb) < 0) + if (cache->fd != fd) { - rtems_rtl_set_error (errno, "file stat failed"); - return false; - } + cache->fd = fd; + + if (fstat (cache->fd, &sb) < 0) + { + rtems_rtl_set_error (errno, "file stat failed"); + return false; + } - cache->file_size = sb.st_size; + cache->file_size = sb.st_size; + } } return false; diff --git a/cpukit/libdl/rtl-trace.c b/cpukit/libdl/rtl-trace.c index fee8de161d..42b3995de5 100644 --- a/cpukit/libdl/rtl-trace.c +++ b/cpukit/libdl/rtl-trace.c @@ -58,6 +58,8 @@ rtems_rtl_trace_shell_command (int argc, char *argv[]) { const char* table[] = { + "detail", + "warning", "load", "unload", "section", @@ -67,7 +69,7 @@ rtems_rtl_trace_shell_command (int argc, char *argv[]) "load-sect", "allocator", "unresolved", - "detail" + "cache" }; rtems_rtl_trace_mask set_value = 0; diff --git a/cpukit/libdl/rtl-trace.h b/cpukit/libdl/rtl-trace.h index 6c060a1519..4b93c8c91c 100644 --- a/cpukit/libdl/rtl-trace.h +++ b/cpukit/libdl/rtl-trace.h @@ -36,18 +36,19 @@ typedef uint32_t rtems_rtl_trace_mask; /** * List of tracing bits for the various parts of the link editor. */ -#define RTEMS_RTL_TRACE_ALL (0xffffffffUL) -#define RTEMS_RTL_TRACE_LOAD (1UL << 0) -#define RTEMS_RTL_TRACE_UNLOAD (1UL << 1) -#define RTEMS_RTL_TRACE_SECTION (1UL << 2) -#define RTEMS_RTL_TRACE_SYMBOL (1UL << 3) -#define RTEMS_RTL_TRACE_RELOC (1UL << 4) -#define RTEMS_RTL_TRACE_GLOBAL_SYM (1UL << 5) -#define RTEMS_RTL_TRACE_LOAD_SECT (1UL << 6) -#define RTEMS_RTL_TRACE_ALLOCATOR (1UL << 7) -#define RTEMS_RTL_TRACE_UNRESOLVED (1UL << 8) -#define RTEMS_RTL_TRACE_DETAIL (1UL << 9) -#define RTEMS_RTL_TRACE_WARNING (1UL << 10) +#define RTEMS_RTL_TRACE_DETAIL (1UL << 0) +#define RTEMS_RTL_TRACE_WARNING (1UL << 1) +#define RTEMS_RTL_TRACE_LOAD (1UL << 2) +#define RTEMS_RTL_TRACE_UNLOAD (1UL << 3) +#define RTEMS_RTL_TRACE_SECTION (1UL << 4) +#define RTEMS_RTL_TRACE_SYMBOL (1UL << 5) +#define RTEMS_RTL_TRACE_RELOC (1UL << 6) +#define RTEMS_RTL_TRACE_GLOBAL_SYM (1UL << 7) +#define RTEMS_RTL_TRACE_LOAD_SECT (1UL << 8) +#define RTEMS_RTL_TRACE_ALLOCATOR (1UL << 9) +#define RTEMS_RTL_TRACE_UNRESOLVED (1UL << 10) +#define RTEMS_RTL_TRACE_CACHE (1UL << 11) +#define RTEMS_RTL_TRACE_ALL (0xffffffffUL & ~(RTEMS_RTL_TRACE_CACHE)) /** * Call to check if this part is bring traced. If RTEMS_RTL_TRACE is defined to |