[haiku-commits] r42598 - in haiku/trunk: headers/private/runtime_loader src/system/libroot/posix src/system/runtime_loader

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 7 Aug 2011 23:01:24 +0200 (CEST)

Author: axeld
Date: 2011-08-07 23:01:23 +0200 (Sun, 07 Aug 2011)
New Revision: 42598
Changeset: https://dev.haiku-os.org/changeset/42598

Modified:
   haiku/trunk/headers/private/runtime_loader/runtime_loader.h
   haiku/trunk/src/system/libroot/posix/dlfcn.c
   haiku/trunk/src/system/runtime_loader/elf.cpp
   haiku/trunk/src/system/runtime_loader/export.cpp
   haiku/trunk/src/system/runtime_loader/images.cpp
   haiku/trunk/src/system/runtime_loader/images.h
   haiku/trunk/src/system/runtime_loader/runtime_loader_private.h
Log:
* Implemented dladdr() in the runtime loader. This is like a gazillion times
  faster than before.
* This also solves a TODO in dladdr(), although I did not use
  get_library_symbol() as I didn't quite see how that could fit as the comment
  suggested; there is now a new function get_symbol_at_address() for this.


Modified: haiku/trunk/headers/private/runtime_loader/runtime_loader.h
===================================================================
--- haiku/trunk/headers/private/runtime_loader/runtime_loader.h 2011-08-07 
20:24:34 UTC (rev 42597)
+++ haiku/trunk/headers/private/runtime_loader/runtime_loader.h 2011-08-07 
21:01:23 UTC (rev 42598)
@@ -1,6 +1,6 @@
 /*
  * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
- * Copyright 2003-2006, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2003-2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  *
  * Copyright 2002, Manuel J. Petit. All rights reserved.
@@ -33,8 +33,11 @@
                int32 symbolType, bool recursive, image_id *_inImage, void 
**_location);
        status_t (*get_library_symbol)(void* handle, void* caller,
                const char* symbolName, void **_location);
-       status_t (*get_nth_image_symbol)(image_id imageID, int32 num, char 
*symbolName,
-               int32 *nameLength, int32 *symbolType, void **_location);
+       status_t (*get_nth_image_symbol)(image_id imageID, int32 num,
+               char *symbolName, int32 *nameLength, int32 *symbolType,
+               void **_location);
+       status_t (*get_symbol_at_address)(void* address, image_id* _imageID,
+               char* nameBuffer, int32* _nameLength, int32* _type, void** 
_location);
        status_t (*test_executable)(const char *path, char *interpreter);
        status_t (*get_next_image_dependency)(image_id id, uint32 *cookie,
                const char **_name);

Modified: haiku/trunk/src/system/libroot/posix/dlfcn.c
===================================================================
--- haiku/trunk/src/system/libroot/posix/dlfcn.c        2011-08-07 20:24:34 UTC 
(rev 42597)
+++ haiku/trunk/src/system/libroot/posix/dlfcn.c        2011-08-07 21:01:23 UTC 
(rev 42598)
@@ -72,60 +72,31 @@
 
 
 int
-dladdr(void *addr, Dl_info *info)
+dladdr(void *address, Dl_info *info)
 {
-// TODO: This can be implemented more efficiently in the runtime loader.
-// get_library_symbol() already has the code doing that.
-       char curSymName[NAME_MAX];
-       static char symName[NAME_MAX];
-       static char imageName[MAXPATHLEN];
-       void *symLocation;
-       int32 cookie;
-       int32 symType, symNameLength;
-       uint32 symIndex;
+       static char sImageName[MAXPATHLEN];
+       static char sSymbolName[NAME_MAX];
+
+       image_id image;
+       int32 nameLength = sizeof(sSymbolName);
+       void* location;
        image_info imageInfo;
+       sStatus = __gRuntimeLoader->get_symbol_at_address(address, &image,
+               sSymbolName, &nameLength, NULL, &location);
+       if (sStatus != B_OK)
+               return 0;
 
-       if (info == NULL)
+       sStatus = get_image_info(image, &imageInfo);
+       if (sStatus != B_OK)
                return 0;
 
-       imageName[0] = '\0';
-       symName[0] = '\0';
-       info->dli_fname = imageName;
-       info->dli_saddr = NULL;
-       info->dli_sname = symName;
+       strlcpy(sImageName, imageInfo.name, MAXPATHLEN);
+       info->dli_fname = sImageName;
+       info->dli_fbase = imageInfo.text;
+       info->dli_sname = sSymbolName;
+       info->dli_saddr = location;
 
-       cookie = 0;
-       while (get_next_image_info(0, &cookie, &imageInfo) == B_OK) {
-               // check if the image holds the symbol
-               if ((addr_t)addr >= (addr_t)imageInfo.text
-                       && (addr_t)addr < (addr_t)imageInfo.text + 
imageInfo.text_size)  {
-                       strlcpy(imageName, imageInfo.name, MAXPATHLEN);
-                       info->dli_fbase = imageInfo.text;
-                       symIndex = 0;
-                       symNameLength = NAME_MAX;
-
-                       while (get_nth_image_symbol(imageInfo.id, symIndex, 
curSymName,
-                                       &symNameLength, &symType, &symLocation) 
== B_OK) {
-                               // check if symbol is the nearest until now
-                               if (symLocation <= addr && symLocation >= 
info->dli_saddr) {
-                                       strlcpy(symName, curSymName, NAME_MAX);
-                                       info->dli_saddr = symLocation;
-
-                                       // stop here if exact match
-                                       if (info->dli_saddr == addr)
-                                               return 1;
-                               }
-                               symIndex++;
-                               symNameLength = NAME_MAX;
-                       }
-                       break;
-               }
-       }
-
-       if (info->dli_saddr != NULL)
-               return 1;
-
-       return 0;
+       return 1;
 }
 
 

Modified: haiku/trunk/src/system/runtime_loader/elf.cpp
===================================================================
--- haiku/trunk/src/system/runtime_loader/elf.cpp       2011-08-07 20:24:34 UTC 
(rev 42597)
+++ haiku/trunk/src/system/runtime_loader/elf.cpp       2011-08-07 21:01:23 UTC 
(rev 42598)
@@ -1,6 +1,6 @@
 /*
  * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
- * Copyright 2003-2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2003-2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  *
  * Copyright 2002, Manuel J. Petit. All rights reserved.
@@ -710,6 +710,57 @@
 
 
 status_t
+get_symbol_at_address(void* address, image_id* _imageID, char* nameBuffer,
+       int32* _nameLength, int32* _type, void** _location)
+{
+       rld_lock();
+
+       image_t* image = find_loaded_image_by_address((addr_t)address);
+       if (image == NULL) {
+               rld_unlock();
+               return B_BAD_VALUE;
+       }
+
+       for (uint32 i = 0; i < HASHTABSIZE(image); i++) {
+               for (int32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
+                               j = HASHCHAINS(image)[j]) {
+                       struct Elf32_Sym *symbol = &image->syms[j];
+                       addr_t location = symbol->st_value + 
image->regions[0].delta;
+
+                       if (location <= (addr_t)address
+                               && location - 1 + symbol->st_size >= 
(addr_t)address) {
+                               const char* symbolName = SYMNAME(image, symbol);
+                               strlcpy(nameBuffer, symbolName, *_nameLength);
+                               *_nameLength = strlen(symbolName);
+
+                               int32 type;
+                               if (ELF32_ST_TYPE(symbol->st_info) == STT_FUNC)
+                                       type = B_SYMBOL_TYPE_TEXT;
+                               else if (ELF32_ST_TYPE(symbol->st_info) == 
STT_OBJECT)
+                                       type = B_SYMBOL_TYPE_DATA;
+                               else
+                                       type = B_SYMBOL_TYPE_ANY;
+                                       // TODO: check with the return types of 
that BeOS function
+
+                               if (_imageID != NULL)
+                                       *_imageID = image->id;
+                               if (_type != NULL)
+                                       *_type = type;
+                               if (_location != NULL)
+                                       *_location = (void*)location;
+
+                               rld_unlock();
+                               return B_OK;
+                       }
+               }
+       }
+
+       rld_unlock();
+       return B_BAD_VALUE;
+}
+
+
+status_t
 get_symbol(image_id imageID, char const *symbolName, int32 symbolType,
        bool recursive, image_id *_inImage, void **_location)
 {

Modified: haiku/trunk/src/system/runtime_loader/export.cpp
===================================================================
--- haiku/trunk/src/system/runtime_loader/export.cpp    2011-08-07 20:24:34 UTC 
(rev 42597)
+++ haiku/trunk/src/system/runtime_loader/export.cpp    2011-08-07 21:01:23 UTC 
(rev 42598)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2003-2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  *
  * Copyright 2002, Manuel J. Petit. All rights reserved.
@@ -51,6 +51,7 @@
        get_symbol,
        get_library_symbol,
        get_nth_symbol,
+       get_symbol_at_address,
        test_executable,
        get_next_image_dependency,
 

Modified: haiku/trunk/src/system/runtime_loader/images.cpp
===================================================================
--- haiku/trunk/src/system/runtime_loader/images.cpp    2011-08-07 20:24:34 UTC 
(rev 42597)
+++ haiku/trunk/src/system/runtime_loader/images.cpp    2011-08-07 21:01:23 UTC 
(rev 42598)
@@ -1,6 +1,6 @@
 /*
  * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
- * Copyright 2003-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2003-2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  *
  * Copyright 2002, Manuel J. Petit. All rights reserved.
@@ -597,6 +597,22 @@
 }
 
 
+image_t*
+find_loaded_image_by_address(addr_t address)
+{
+       for (image_t* image = sLoadedImages.head; image; image = image->next) {
+               for (uint32 i = 0; i < image->num_regions; i++) {
+                       elf_region_t& region = image->regions[i];
+                       if (region.vmstart <= address
+                               && region.vmstart - 1 + region.vmsize >= 
address)
+                               return image;
+               }
+       }
+
+       return NULL;
+}
+
+
 void
 set_image_flags_recursively(image_t* image, uint32 flags)
 {

Modified: haiku/trunk/src/system/runtime_loader/images.h
===================================================================
--- haiku/trunk/src/system/runtime_loader/images.h      2011-08-07 20:24:34 UTC 
(rev 42597)
+++ haiku/trunk/src/system/runtime_loader/images.h      2011-08-07 21:01:23 UTC 
(rev 42598)
@@ -1,6 +1,6 @@
 /*
  * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
- * Copyright 2003-2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2003-2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  *
  * Copyright 2002, Manuel J. Petit. All rights reserved.
@@ -66,6 +66,7 @@
 
 image_t*       find_loaded_image_by_name(char const* name, uint32 typeMask);
 image_t*       find_loaded_image_by_id(image_id id, bool ignoreDisposable);
+image_t*       find_loaded_image_by_address(addr_t address);
 
 void           set_image_flags_recursively(image_t* image, uint32 flags);
 void           clear_image_flags_recursively(image_t* image, uint32 flags);

Modified: haiku/trunk/src/system/runtime_loader/runtime_loader_private.h
===================================================================
--- haiku/trunk/src/system/runtime_loader/runtime_loader_private.h      
2011-08-07 20:24:34 UTC (rev 42597)
+++ haiku/trunk/src/system/runtime_loader/runtime_loader_private.h      
2011-08-07 21:01:23 UTC (rev 42598)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2003-2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  *
  * Copyright 2002, Manuel J. Petit. All rights reserved.
@@ -65,6 +65,8 @@
 status_t unload_library(void* handle, image_id imageID, bool addOn);
 status_t get_nth_symbol(image_id imageID, int32 num, char* nameBuffer,
        int32* _nameLength, int32* _type, void** _location);
+status_t get_symbol_at_address(void* address, image_id* _imageID,
+       char* nameBuffer, int32* _nameLength, int32* _type, void** _location);
 status_t get_symbol(image_id imageID, char const* symbolName, int32 symbolType,
        bool recursive, image_id* _inImage, void** _location);
 status_t get_library_symbol(void* handle, void* caller, const char* symbolName,


Other related posts:

  • » [haiku-commits] r42598 - in haiku/trunk: headers/private/runtime_loader src/system/libroot/posix src/system/runtime_loader - axeld