OSDN Git Service

patch from Bernd Schmidt to abstract away load address checks
authorMike Frysinger <vapier@gentoo.org>
Wed, 5 Jul 2006 19:05:55 +0000 (19:05 -0000)
committerMike Frysinger <vapier@gentoo.org>
Wed, 5 Jul 2006 19:05:55 +0000 (19:05 -0000)
ldso/include/dl-defs.h
ldso/libdl/libdl.c

index 2d4f1d6..18f718b 100644 (file)
@@ -75,4 +75,19 @@ typedef struct {
        ((LOADADDR) = (BASEADDR))
 #endif
 
+/* Test whether a given ADDR is more likely to be within the memory
+ * region mapped to TPNT (a struct elf_resolve *) than to TFROM.
+ * Everywhere that this is used, TFROM is initially NULL, and whenever
+ * a potential match is found, it's updated.  One might want to walk
+ * the chain of elf_resolve to locate the best match and return false
+ * whenever TFROM is non-NULL, or use an exact-matching algorithm
+ * using additional information encoded in DL_LOADADDR_TYPE to test
+ * for exact containment.
+ */
+#ifndef DL_ADDR_IN_LOADADDR
+# define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
+       ((void*)(TPNT)->loadaddr < (void*)(ADDR) \
+        && (!(TFROM) || (TFROM)->loadaddr < (TPNT)->loadaddr))
+#endif
+
 #endif /* _LD_DEFS_H */
index 3222308..418a720 100644 (file)
@@ -175,8 +175,7 @@ void *dlopen(const char *libname, int flag)
                tfrom = NULL;
                for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {
                        tpnt = dpnt->dyn;
-                       if (tpnt->loadaddr < from
-                                       && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
+                       if (DL_ADDR_IN_LOADADDR(from, tpnt, tfrom))
                                tfrom = tpnt;
                }
        }
@@ -436,8 +435,7 @@ void *dlsym(void *vhandle, const char *name)
                tfrom = NULL;
                for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next) {
                        tpnt = rpnt->dyn;
-                       if (tpnt->loadaddr < from
-                                       && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) {
+                       if (DL_ADDR_IN_LOADADDR(from, tpnt, tfrom)) {
                                tfrom = tpnt;
                                handle = rpnt->next;
                        }
@@ -664,10 +662,8 @@ int dladdr(const void *__address, Dl_info * __info)
                fprintf(stderr, "Module \"%s\" at %p\n",
                                tpnt->libname, tpnt->loadaddr);
 #endif
-               if (tpnt->loadaddr < (ElfW(Addr)) __address
-                               && (pelf == NULL || pelf->loadaddr < tpnt->loadaddr)) {
+               if (DL_ADDR_IN_LOADADDR((ElfW(Addr)) __address,  tpnt, pelf))
                        pelf = tpnt;
-               }
        }
 
        if (!pelf) {