Subject: Re: bug#2507: 23.0.91; Stripping emacs.exe on MS-Windows produces an invalid program

From: Eli Zaretskii <[email-masked]>
Date: Sun, 07 Apr 2013 19:44:28 +0300

> From: Jason Rumney <[email-masked]>
> Date: Wed, 13 Jul 2011 22:16:36 +0800
> Cc: Juanma Barranquero <[email-masked]>,
> 	Lars Magne Ingebrigtsen <[email-masked]>, [email-masked]
> 
> If you build without debug info in the first place, it does work, at
> around the same size. Also if you strip temacs before dumping, it
> works. The problem is only in stripping a dumped binary that had
> debug info to start with. It seems the strip command removes some info
> that Emacs needs to reconstruct the heap from the dumped image.

That is correct.

I looked into this some more.  The problem is that we add an extra
section to the Emacs executable (by running addsection), which serves
as the static heap.  Here's the report from "objdump -h":

  temacs.exe:     file format pei-i386

  Sections:
  Idx Name          Size      VMA       LMA       File off  Algn
    0 .text         0032e604  01001000  01001000  00001000  2**4
		    CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
    1 .data         0020aea0  01330000  01330000  00330000  2**4
		    CONTENTS, ALLOC, LOAD, DATA
    2 .rdata        000dc57c  0153b000  0153b000  0053b000  2**4
		    CONTENTS, ALLOC, LOAD, READONLY, DATA
    3 .bss          0005c410  01618000  01618000  00000000  2**4
		    ALLOC
    4 .idata        000036f4  01675000  01675000  00618000  2**2
		    CONTENTS, ALLOC, LOAD, DATA
    5 .rsrc         0000d5f0  01679000  01679000  0061c000  2**2
		    CONTENTS, ALLOC, LOAD, DATA
    6 .debug_aranges 00000ce0  01687000  01687000  0062a000  2**0
		    CONTENTS, READONLY, DEBUGGING
    7 .debug_pubnames 00011b5a  01688000  01688000  0062b000  2**0
		    CONTENTS, READONLY, DEBUGGING
    8 .debug_info   003992b0  0169a000  0169a000  0063d000  2**0
		    CONTENTS, READONLY, DEBUGGING
    9 .debug_abbrev 0001181b  01a34000  01a34000  009d7000  2**0
		    CONTENTS, READONLY, DEBUGGING
   10 .debug_line   0003f37e  01a46000  01a46000  009e9000  2**0
		    CONTENTS, READONLY, DEBUGGING
   11 .debug_frame  0001b6b8  01a86000  01a86000  00a29000  2**0
		    CONTENTS, READONLY, DEBUGGING
   12 .debug_str    0000d3bb  01aa2000  01aa2000  00a45000  2**0
		    CONTENTS, READONLY, DEBUGGING
   13 .debug_macinfo 01b54308  01ab0000  01ab0000  00a53000  2**0
		    CONTENTS, READONLY, DEBUGGING
   14 EMHEAP        01b00000  03605000  03605000  00000000  2**2
		    ALLOC

The last section, EMHEAP, is the one we add.  Now look what happens
after stripping:

  temacs.exe:     file format pei-i386

  Sections:
  Idx Name          Size      VMA       LMA       File off  Algn
    0 .text         0032e604  01001000  01001000  00000400  2**4
		    CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
    1 .data         0020aea0  01330000  01330000  0032ec00  2**4
		    CONTENTS, ALLOC, LOAD, DATA
    2 .rdata        000dc57c  0153b000  0153b000  00539c00  2**4
		    CONTENTS, ALLOC, LOAD, READONLY, DATA
    3 .bss          0005c410  01618000  01618000  00000000  2**4
		    ALLOC
    4 .idata        000036f4  01675000  01675000  00616200  2**2
		    CONTENTS, ALLOC, LOAD, DATA
    5 .rsrc         0000d5f0  01679000  01679000  00619a00  2**2
		    CONTENTS, ALLOC, LOAD, DATA
    6 EMHEAP        01b00000  03605000  03605000  00000000  2**2
		    ALLOC

The debug sections are gone, but the VMA and LMA of EMHEAP were left
intact.  By contrast, if we strip temacs.bin _before_ running
addsection, and run addsection on the stripped temacs.bin, we get
this:

  temacs.exe:     file format pei-i386

  Sections:
  Idx Name          Size      VMA       LMA       File off  Algn
    0 .text         0032e604  01001000  01001000  00001000  2**4
		    CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
    1 .data         0020aea0  01330000  01330000  00330000  2**4
		    CONTENTS, ALLOC, LOAD, DATA
    2 .rdata        000dc57c  0153b000  0153b000  0053b000  2**4
		    CONTENTS, ALLOC, LOAD, READONLY, DATA
    3 .bss          0005c410  01618000  01618000  00000000  2**4
		    ALLOC
    4 .idata        000036f4  01675000  01675000  00618000  2**2
		    CONTENTS, ALLOC, LOAD, DATA
    5 .rsrc         0000d5f0  01679000  01679000  0061c000  2**2
		    CONTENTS, ALLOC, LOAD, DATA
    6 EMHEAP        01b00000  01687000  01687000  00000000  2**2
		    ALLOC

Now EMHEAP's VMA and LMA follow the section before it.

So I think the kind of workaround mentioned in

  http://debbugs.gnu.org/cgi/bugreport.cgi?bug=2507#10

above, or some variant thereof, is the right way of producing a
stripped emacs.exe.  That is, link with -s (or strip temacs.bin after
it is produced), and then run addsection to produce temacs.exe and
finally loadup+dump into emacs.exe.

An alternative is to add code to addsection.c so that it could adjust
the EMHEAP section's VMA and LMA after emacs.exe was stripped.  No,
I'm not volunteering ;-)

P.S. I tried to adjust the VMA/LMA with objcopy, but the result is not
reliable: sometimes works, sometimes crashes.  So more than just
address adjustment is needed.