public inbox for cygwin-apps@cygwin.com
 help / color / mirror / Atom feed
* [rebase/patch] Support IMAGE_REL_BASED_DIR64 relocations
@ 2013-01-15 12:38 Corinna Vinschen
  2013-01-16  1:09 ` Jason Tishler
  0 siblings, 1 reply; 3+ messages in thread
From: Corinna Vinschen @ 2013-01-15 12:38 UTC (permalink / raw)
  To: Jason Tishler; +Cc: cygwin-apps

Hi Jason,

While looking into Marco's rebase problem I noticed that 64 bit support
in rebase was not complete.  64 bit uses IMAGE_REL_BASED_DIR64 relocation
entries, which were simply ignored since only the 32 bit variation
IMAGE_REL_BASED_HIGHLOW was supported at all.  Also, it would have been
impossible to relocate 64 bit DLLs to addresses beyond the 4GB border
since the offset difference was kept as an int value.  The below patch
fixes both oversight.

Ok to apply?


Thanks,
Corinna


	* objectfile.h (LinkedObjectFile::performRelocation): Change type of
	parameter to int64_t.
	* rebaseimage.cc (ReBaseImage64): Change type of local variable
	difference to int64_t.
	* sections.cc (Relocations::check): Fix formatting.
	(Relocations::relocate): Take difference parameter as int64_t.  Call
	cursec->debugprint rather than cursec->print and drop FIXME comment.
	Handle Windows relocation info types IMAGE_REL_BASED_ABSOLUTE,
	IMAGE_REL_BASED_HIGHLOW and IMAGE_REL_BASED_DIR64.  Print error
	output if another relocation type is found.  Fix formatting.
	* sections.h (Relocations::relocate): Change type of parameter to
	int64_t.


Index: imagehelper/objectfile.h
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/imagehelper/objectfile.h,v
retrieving revision 1.6
diff -u -p -r1.6 objectfile.h
--- imagehelper/objectfile.h	19 Mar 2012 17:57:49 -0000	1.6
+++ imagehelper/objectfile.h	15 Jan 2013 12:35:45 -0000
@@ -125,7 +125,7 @@ class LinkedObjectFile : public ObjectFi
     {
       return relocs->fix();
     }
-    bool performRelocation(int difference)
+    bool performRelocation(int64_t difference)
     {
       return relocs->relocate(difference);
     }
Index: imagehelper/rebaseimage.cc
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/imagehelper/rebaseimage.cc,v
retrieving revision 1.6
diff -u -p -r1.6 rebaseimage.cc
--- imagehelper/rebaseimage.cc	30 Apr 2012 13:37:16 -0000	1.6
+++ imagehelper/rebaseimage.cc	15 Jan 2013 12:35:45 -0000
@@ -118,7 +118,7 @@ BOOL ReBaseImage64 (
       ntheader32->FileHeader.TimeDateStamp = TimeStamp;
     }
 
-  int difference = *NewImageBase - *OldImageBase;
+  int64_t difference = *NewImageBase - *OldImageBase;
 
   if (!dll.performRelocation(difference))
     {
Index: imagehelper/sections.cc
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/imagehelper/sections.cc,v
retrieving revision 1.4
diff -u -p -r1.4 sections.cc
--- imagehelper/sections.cc	8 Jul 2011 07:18:55 -0000	1.4
+++ imagehelper/sections.cc	15 Jan 2013 12:35:45 -0000
@@ -302,14 +302,15 @@ bool Relocations::check(void)
       int NumOfRelocs = (relocp->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof (WORD);
       int va = relocp->VirtualAddress;
       PWORD p = (PWORD)((uintptr_t)relocp + sizeof(IMAGE_BASE_RELOCATION));
-	    if (debug)
-	      	std::cerr << "debug: blocksize= " << std::dec << NumOfRelocs << std::endl;
+      if (debug)
+	  std::cerr << "debug: blocksize= " << std::dec << NumOfRelocs << std::endl;
 
       cursec = sections->find(va);
-	    if (debug) {
-	      	std::cerr << "debug: section= "; 
-	      	cursec->debugprint();
-      }
+      if (debug)
+        {
+	  std::cerr << "debug: section= "; 
+	  cursec->debugprint();
+	}
       if (!cursec)
         {
           if (debug)
@@ -319,11 +320,12 @@ bool Relocations::check(void)
           errors++;
           continue;
         }
-	    for (int i = 0; i < NumOfRelocs; i++,p++) {
-		    int location = (*p & 0x0fff) + va;
-	      if (debug)
-	      	std::cerr << "debug: location= 0x" << std::setw(8) << std::setfill('0') << std::hex << location << std::endl;
-		  }
+      if (debug)
+	for (int i = 0; i < NumOfRelocs; i++,p++)
+	  {
+	    int location = (*p & 0x0fff) + va;
+	    std::cerr << "debug: location= 0x" << std::setw(8) << std::setfill('0') << std::hex << location << std::endl;
+	  }
     }
   return errors == 0;
 }
@@ -365,7 +367,7 @@ bool Relocations::fix(void)
 }
 
 
-bool Relocations::relocate(int difference)
+bool Relocations::relocate(int64_t difference)
 {
   PIMAGE_BASE_RELOCATION relocp = relocs;
   int WholeNumOfRelocs = 0;
@@ -386,8 +388,6 @@ bool Relocations::relocate(int differenc
         }
       WholeNumOfRelocs += NumOfRelocs;
 
-      int adjust;
-
       Section *cursec = sections->find(va);
       if (!cursec)
         {
@@ -398,29 +398,55 @@ bool Relocations::relocate(int differenc
         	return false;
         }
       else if (debug)
-        // FIXME: this goes to cout but debug message should go to cerr
-        cursec->print("currently relocated section");
-      adjust = cursec->getAdjust();
+        cursec->debugprint("currently relocated section");
+
+      int adjust = cursec->getAdjust();
 
       for (int i = 0; i < NumOfRelocs; i++,p++)
         {
-          if ((*p & 0xf000) == 0x3000)
-            {
-              int location = (*p & 0x0fff) + va;
-              if (debug)
-                {
-                  std::cerr << "0x" \
-                  << std::setw(8) << std::setfill('0') << std::hex << location << std::dec \
-                  << " - ";
-                  std::cerr << "0x" \
-                  << std::setw(8) << std::setfill('0') << std::hex << location + adjust + 3 << std::dec \
-                  << std::endl;
-                }
-              int *patch_adr = (int *)cursec->rva2real(location);
-              *patch_adr += difference;
-            }
+	  WORD rel_type = (*p & 0xf000) >> 12;
+	  int location = (*p & 0x0fff) + va;
+
+	  switch (rel_type)
+	    {
+	    case IMAGE_REL_BASED_ABSOLUTE:
+	      break;
+	    case IMAGE_REL_BASED_HIGHLOW:
+	      {
+		if (debug)
+		  {
+		    std::cerr << "HIGHLOW: 0x" \
+		    << std::setw(8) << std::setfill('0') << std::hex << location << std::dec \
+		    << " - ";
+		    std::cerr << "0x" \
+		    << std::setw(8) << std::setfill('0') << std::hex << location + adjust + 3 << std::dec \
+		    << std::endl;
+		  }
+		int32_t *patch_adr = (int *)cursec->rva2real(location);
+		*patch_adr += difference;
+	      }
+	      break;
+	    case IMAGE_REL_BASED_DIR64:
+	      {
+		if (debug)
+		  {
+		    std::cerr << "  DIR64: 0x" \
+		    << std::setw(16) << std::setfill('0') << std::hex << location << std::dec \
+		    << " - ";
+		    std::cerr << "0x" \
+		    << std::setw(16) << std::setfill('0') << std::hex << location + adjust + 7 << std::dec \
+		    << std::endl;
+		  }
+		int64_t *patch_adr = (int64_t *)cursec->rva2real(location);
+		*patch_adr += difference;
+	      }
+	      break;
+	    default:
+	      std::cerr << "Unsupported relocation type " << rel_type << std::endl;
+	      break;
+	    }
         }
     }
-	return true;
+  return true;
 }
 
Index: imagehelper/sections.h
===================================================================
RCS file: /sourceware/projects/cygwin-apps-home/cvsfiles/rebase/imagehelper/sections.h,v
retrieving revision 1.5
diff -u -p -r1.5 sections.h
--- imagehelper/sections.h	29 Jul 2011 13:17:44 -0000	1.5
+++ imagehelper/sections.h	15 Jan 2013 12:35:45 -0000
@@ -210,7 +210,7 @@ class Relocations : SectionBase
     bool fix(void);
 
     // precondition: fixed dll
-    bool relocate(int difference);
+    bool relocate(int64_t difference);
 
   private:
     PIMAGE_BASE_RELOCATION relocs;


-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [rebase/patch] Support IMAGE_REL_BASED_DIR64 relocations
  2013-01-15 12:38 [rebase/patch] Support IMAGE_REL_BASED_DIR64 relocations Corinna Vinschen
@ 2013-01-16  1:09 ` Jason Tishler
  2013-01-16 12:48   ` Corinna Vinschen
  0 siblings, 1 reply; 3+ messages in thread
From: Jason Tishler @ 2013-01-16  1:09 UTC (permalink / raw)
  To: cygwin-apps

Corinna,

On Tue, Jan 15, 2013 at 01:37:10PM +0100, Corinna Vinschen wrote:
> While looking into Marco's rebase problem I noticed that 64 bit support
> in rebase was not complete.  64 bit uses IMAGE_REL_BASED_DIR64 relocation
> entries, which were simply ignored since only the 32 bit variation
> IMAGE_REL_BASED_HIGHLOW was supported at all.  Also, it would have been
> impossible to relocate 64 bit DLLs to addresses beyond the 4GB border
> since the offset difference was kept as an int value.  The below patch
> fixes both oversight.
> 
> Ok to apply?

Yes.  Let me know when you are ready and I will make a release.

Thanks,
Jason

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [rebase/patch] Support IMAGE_REL_BASED_DIR64 relocations
  2013-01-16  1:09 ` Jason Tishler
@ 2013-01-16 12:48   ` Corinna Vinschen
  0 siblings, 0 replies; 3+ messages in thread
From: Corinna Vinschen @ 2013-01-16 12:48 UTC (permalink / raw)
  To: cygwin-apps

On Jan 15 20:08, Jason Tishler wrote:
> Corinna,
> 
> On Tue, Jan 15, 2013 at 01:37:10PM +0100, Corinna Vinschen wrote:
> > While looking into Marco's rebase problem I noticed that 64 bit support
> > in rebase was not complete.  64 bit uses IMAGE_REL_BASED_DIR64 relocation
> > entries, which were simply ignored since only the 32 bit variation
> > IMAGE_REL_BASED_HIGHLOW was supported at all.  Also, it would have been
> > impossible to relocate 64 bit DLLs to addresses beyond the 4GB border
> > since the offset difference was kept as an int value.  The below patch
> > fixes both oversight.
> > 
> > Ok to apply?
> 
> Yes.  Let me know when you are ready and I will make a release.

Done.  The actual problem Marco is encountering is a binutils problem,
apparently.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-01-16 12:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-15 12:38 [rebase/patch] Support IMAGE_REL_BASED_DIR64 relocations Corinna Vinschen
2013-01-16  1:09 ` Jason Tishler
2013-01-16 12:48   ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).