Index: trunk/src/kernel32/winimagepe2lx.cpp
===================================================================
--- trunk/src/kernel32/winimagepe2lx.cpp	(revision 4366)
+++ trunk/src/kernel32/winimagepe2lx.cpp	(revision 4368)
@@ -1,3 +1,3 @@
-/* $Id: winimagepe2lx.cpp,v 1.16 2000-10-02 04:00:35 bird Exp $ */
+/* $Id: winimagepe2lx.cpp,v 1.17 2000-10-02 13:35:23 bird Exp $ */
 
 /*
@@ -324,48 +324,61 @@
         {
             PVOID pv;
-            ULONG ulBorlandRVAFix = 0UL;
 
             /*
-             * Borland seems to have problems getting things right...
-             *      Uses real pointers with baserelocations.
-             * Needs to subtract image loadaddress to make the TLSDir them RVAs.
+             * According to the docs StartAddressOfRawData and EndAddressOfRawData is
+             * real pointers with a baserelocs.
              *
-             * We'll check if the StartAddressOfRawData pointer is an RVA or an real address by
-             * check if it is within the TLS section or not.
-             * ASSUMES: StartAddressOfRawData is in the same section as the TLS Directory.
+             * The docs says nothing about the two AddressOf pointers. So, we'll assume that
+             * these also are real pointers. But, we'll try compensate if they should not have
+             * base realocations.
              */
-            if (paSections[iSection].ulRVA > pTLSDir->StartAddressOfRawData ||
-                paSections[iSection].ulRVA + paSections[iSection].cbVirtual <= pTLSDir->StartAddressOfRawData)
-                { /* StartAddressOfRawData was not an RVA within the same section as the TLS directory */
-                ulBorlandRVAFix = paSections[iSection].ulAddress - paSections[iSection].ulRVA;
+            if (validateRealPointer((PVOID)pTLSDir->StartAddressOfRawData)
+                &&
+                validateRealPointer((PVOID)pTLSDir->EndAddressOfRawData)
+                )
+            {
+                setTLSAddress((PVOID)pTLSDir->StartAddressOfRawData);
+                setTLSInitSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData);
+                setTLSTotalSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData + pTLSDir->SizeOfZeroFill);
+
+                if (pTLSDir->AddressOfIndex)
+                {
+                    if (validateRealPointer(pTLSDir->AddressOfIndex))
+                        /* assume baserelocations for thepointer; use it without any change. */
+                        setTLSIndexAddr((LPDWORD)(void*)pTLSDir->AddressOfIndex);
+                    else
+                    {   /* assume no baserelocs for these pointers? Complain and debugint3 */
+                        eprintf(("Win32Pe2LxImage::init: TLS - AddressOfIndex(%#8x) is not a pointer with basereloc.\n",
+                                 pTLSDir->AddressOfIndex));
+                        pv = getPointerFromPointer(pTLSDir->AddressOfIndex);
+                        if (pv == NULL)
+                        {
+                            eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS AddressOfIndex - %#8x.\n",
+                                     pTLSDir->AddressOfIndex));
+                            return FALSE;
+                        }
+                        setTLSIndexAddr((LPDWORD)pv);
+                    }
                 }
-            pv = getPointerFromRVA(pTLSDir->StartAddressOfRawData - ulBorlandRVAFix);
-            if (pv == NULL || pTLSDir->StartAddressOfRawData == 0UL)
-            {
-                eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS StartAddressOfRawData - %#8x.\n",
-                         pTLSDir->StartAddressOfRawData));
-                return FALSE;
-            }
-            setTLSAddress(pv);
-            setTLSInitSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData);
-            setTLSTotalSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData + pTLSDir->SizeOfZeroFill);
-            pv = getPointerFromRVA((ULONG)pTLSDir->AddressOfIndex - ulBorlandRVAFix);
-            if (pv == NULL)
-            {
-                eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS AddressOffIndex - %#8x.\n",
-                         pTLSDir->AddressOfIndex));
-                return FALSE;
-            }
-            setTLSIndexAddr((LPDWORD)pv);
-            if (pTLSDir->AddressOfCallBacks != 0)
-            {
-                pv = getPointerFromRVA((ULONG)pTLSDir->AddressOfCallBacks - ulBorlandRVAFix);
-                if (pv == NULL)
+
+                if (pTLSDir->AddressOfCallBacks)
                 {
-                    eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS AddressOffIndex - %#8x.\n",
-                             pTLSDir->AddressOfIndex));
-                    return FALSE;
+                    if (validateRealPointer(pTLSDir->AddressOfCallBacks))
+                        /* assume baserelocations for thepointer; use it without any change. */
+                        setTLSCallBackAddr(pTLSDir->AddressOfCallBacks);
+                    else
+                    {   /* assume no baserelocs for these pointers? Complain and debugint3 */
+                        eprintf(("Win32Pe2LxImage::init: Warning: TLS - AddressOfCallBacks(%#8x) is not a pointer with basereloc.\n",
+                                 pTLSDir->AddressOfCallBacks));
+                        pv = getPointerFromPointer(pTLSDir->AddressOfCallBacks);
+                        if (pv == NULL)
+                        {
+                            eprintf(("Win32Pe2LxImage::init: invalid pointer to TLS AddressOfCallBacks - %#8x.\n",
+                                     pTLSDir->AddressOfIndex));
+                            return FALSE;
+                        }
+                        setTLSCallBackAddr((PIMAGE_TLS_CALLBACK*)pv);
+                    }
                 }
-                setTLSCallBackAddr((PIMAGE_TLS_CALLBACK*)pv);
             }
         }
@@ -700,7 +713,11 @@
 {
     int i;
+
     #ifdef DEBUG
-        if (paSections == NULL)
-            return NULL;
+    if (paSections == NULL)
+    {
+        eprintf(("Win32Pe2LxImage::getPointerFromRVA: paSections is NULL!\n"));
+        return NULL;
+    }
     #endif
 
@@ -710,5 +727,5 @@
     i = 0;
     while (i < cSections &&
-           !(paSections[i].ulRVA <= ulRVA && paSections[i].ulRVA + paSections[i].cbVirtual > ulRVA)) /* ALIGN on page too? */
+           (paSections[i].ulRVA > ulRVA || paSections[i].ulRVA + paSections[i].cbVirtual <= ulRVA)) /* ALIGN on page too? */
         i++;
 
@@ -717,4 +734,20 @@
 
     return (PVOID)(ulRVA - paSections[i].ulRVA + paSections[i].ulAddress);
+}
+
+
+/**
+ * Converts a pointer with not basereloc to a pointer.
+ * @returns Pointer with baserelocation applied.
+ * @param   pv  Pointer without baserelocation.
+ * @status  completely implemented.
+ * @author  knut st. osmundsen (knut.stange.osmundsen@mynd.no)
+ */
+PVOID  Win32Pe2LxImage::getPointerFromPointer(PVOID pv)
+{
+    if (pv == NULL)
+        return NULL;
+
+    return getPointerFromRVA((ULONG)pv - pNtHdrs->OptionalHeader.ImageBase);
 }
 
@@ -739,7 +772,11 @@
 {
     LONG i;
+
     #ifdef DEBUG
-        if (paSections == NULL)
-            return -1;
+    if (paSections == NULL)
+    {
+        eprintf(("Win32Pe2LxImage::getSectionIndexFromRVA: paSections is NULL!\n"));
+        return NULL;
+    }
     #endif
 
@@ -749,8 +786,44 @@
     i = 0;
     while (i < cSections &&
-           !(paSections[i].ulRVA <= ulRVA && paSections[i].ulRVA + paSections[i].cbVirtual > ulRVA)) /* ALIGN on page too? */
+           (paSections[i].ulRVA > ulRVA && paSections[i].ulRVA + paSections[i].cbVirtual <= ulRVA)) /* ALIGN on page too? */
         i++;
 
     return i < cSections ? i : -1;
+}
+
+
+/**
+ * Validates that a given pointer is pointing to valid memory within
+ * the loaded executable image.
+ * @returns TRUE if the pointer is valid.
+ *          FALSE if the pointer is invalid.
+ * @param   pv  Pointer to validate.
+ * @sketch
+ * @status  completely implemented.
+ * @author  knut st. osmundsen (knut.stange.osmundsen@mynd.no)
+ */
+BOOL Win32Pe2LxImage::validateRealPointer(PVOID pv)
+{
+    int i;
+
+    #ifdef DEBUG
+    if (paSections == NULL)
+    {
+        eprintf(("Win32Pe2LxImage::validateRealPointer: paSections is NULL!\n"));
+        return NULL;
+    }
+    #endif
+
+    if (pv == NULL)
+        return FALSE;
+
+    i = 0;
+    while (i < cSections &&
+           (paSections[i].ulAddress < (ULONG)pv ||
+            paSections[i].ulAddress + paSections[i].cbVirtual <= (ULONG)pv) /* Align on page too? */
+           )
+        i++;
+
+    return i < cSections;
 }
 
Index: trunk/src/kernel32/winimagepe2lx.h
===================================================================
--- trunk/src/kernel32/winimagepe2lx.h	(revision 4366)
+++ trunk/src/kernel32/winimagepe2lx.h	(revision 4368)
@@ -1,3 +1,3 @@
-/* $Id: winimagepe2lx.h,v 1.5 2000-10-02 04:00:36 bird Exp $ */
+/* $Id: winimagepe2lx.h,v 1.6 2000-10-02 13:35:23 bird Exp $ */
 
 /*
@@ -57,5 +57,7 @@
     /* these should be moved to winimagebase some day... */
     PVOID    getPointerFromRVA(ULONG ulRVA);
+    PVOID    getPointerFromPointer(PVOID pv);
     LONG     getSectionIndexFromRVA(ULONG ulRVA);
+    BOOL     validateRealPointer(PVOID pv);
 
     PSECTION            paSections; /* Used by getPointerFromRVA and created by getSections and
