From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8313 invoked by alias); 15 Jan 2013 12:38:01 -0000 Received: (qmail 6617 invoked by uid 22791); 15 Jan 2013 12:37:24 -0000 X-Spam-Check-By: sourceware.org Received: from aquarius.hirmke.de (HELO calimero.vinschen.de) (217.91.18.234) by sourceware.org (qpsmtpd/0.83/v0.83-20-g38e4449) with ESMTP; Tue, 15 Jan 2013 12:37:13 +0000 Received: by calimero.vinschen.de (Postfix, from userid 500) id A07C6521456; Tue, 15 Jan 2013 13:37:10 +0100 (CET) Date: Tue, 15 Jan 2013 12:38:00 -0000 From: Corinna Vinschen To: Jason Tishler Cc: cygwin-apps@cygwin.com Subject: [rebase/patch] Support IMAGE_REL_BASED_DIR64 relocations Message-ID: <20130115123710.GA18986@calimero.vinschen.de> Reply-To: cygwin-apps@cygwin.com Mail-Followup-To: Jason Tishler , cygwin-apps@cygwin.com MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Mailing-List: contact cygwin-apps-help@cygwin.com; run by ezmlm Precedence: bulk Sender: cygwin-apps-owner@cygwin.com List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Mail-Followup-To: cygwin-apps@cygwin.com X-SW-Source: 2013-01/txt/msg00042.txt.bz2 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