Bug 21459 - Wrong location for .debug_gdb_scripts on Windows
Summary: Wrong location for .debug_gdb_scripts on Windows
Status: ASSIGNED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-05-04 12:55 UTC by Egon Elbre
Modified: 2017-05-15 13:42 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2017-05-12 00:00:00


Attachments
Proposed patch (1.02 KB, patch)
2017-05-09 16:43 UTC, Nick Clifton
Details | Diff
Linker script fragment (117 bytes, text/plain)
2017-05-10 08:47 UTC, Nick Clifton
Details
Proposed patch (1.53 KB, patch)
2017-05-11 13:14 UTC, Nick Clifton
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Egon Elbre 2017-05-04 12:55:23 UTC
While debugging go compilation issue (https://github.com/golang/go/issues/20183)
we trace it to ld placing .debug_gdb_scripts to a wrong location for Windows.

Easiest test-case:

    int main(int argc, char const *argv[]) { return 0; }
    __attribute__ ((section(".debug_gdb_scripts")))
    char data[] = "debug.py";

  > gcc -o example.exe example.c && example.exe
    Access Denied

This also happens when you use any other random .debug_* section... e.g.

    int main(int argc, char const *argv[]) { return 0; }
    __attribute__ ((section(".debug_zzz")))
    char data[] = "debug.py";

Suggestion from Ian Lance Taylor (https://github.com/golang/go/issues/20183#issuecomment-299167976):

> The GNU linker source files that fail to list the .debug_gdb_scripts 
> section are ld/scripttempl/pe.sc and ld/scripttempl/pep.sc.
> The best fix is to handle this case in gld_${EMULATION_NAME}_place_orphan 
> in ld/emultempl/pe.em and ld/emultempl/pep.em.
Comment 1 Nick Clifton 2017-05-09 16:43:38 UTC
Created attachment 10043 [details]
Proposed patch

Hi Egon,

  Please could you try out this patch ?

  I think that it should work for debugging sections (ie ones starting with
  .debug) but it may not solve the general problem of an arbitrary named,
  non-empty, non-loaded section being placed at VMA 0.

Cheers
  Nick
Comment 2 Egon Elbre 2017-05-10 07:38:58 UTC
(In reply to Nick Clifton from comment #1)
> Created attachment 10043 [details]
> Proposed patch
> 
> Hi Egon,
> 
>   Please could you try out this patch ?

I can certainly try :D

But trying to compile anything involving configure and make on Windows has always been problematic for me.

/Currently in my third hour trying to test it. Managed to finally compile ld-new, but not quite sure whether I've made a mistake in compiling or invoking gcc/ld... or the patch wasn't sufficient. I think my mistake is more likely. But, it does look like it's using new linker and doesn't create a valid executable. Will investigate further./

> 
>   I think that it should work for debugging sections (ie ones starting with
>   .debug) but it may not solve the general problem of an arbitrary named,
>   non-empty, non-loaded section being placed at VMA 0.

A quick question,

Is there a workaround to coerce the unfixed ld to behave similarly via command-line flags or some config script?

The best idea we have so far, is to compile with `.xxxxx_gdb_scripts` and then rename it with `objcopy --rename-section .xxxxx_gdb_scripts=.debug_gdb_scripts`.

> 
> Cheers
>   Nick
Comment 3 Nick Clifton 2017-05-10 08:47:02 UTC
Created attachment 10044 [details]
Linker script fragment

Hi Egon,

> But, it does look like it's using new linker and doesn't create a valid 
> executable. Will investigate further.

Darn!  I assume that the problem is still the same - ie the .debug_gdb_scripts section is still being placed at VMA 0 ?

> A quick question,

> Is there a workaround to coerce the unfixed ld to behave similarly via 
> command-line flags or some config script?

Actually, yes there is. :-)  Have a look at the attached linker script fragment.
It tells the linker exactly where it should place the .debug_gdb_scripts section.  You can use this fragment to augment the already existing, built-in, linker script by using this on your linker command line:

  -T debug.ld

or if you are using gcc or g++:

  -Wl,-T,debug.ld

Now this fix will only work for the .debug_gdb_scripts section, but you can easily edit the debug.ld file and add in other problematic sections as you wish.

You may ask, "why not just add these sections to the built-in linker script ?".  We could - but - that would only solve the problem for those specific sections.  The patch that I created is intended to work for any .debug_xxx section, regardless of its name.

Cheers
  Nick
Comment 4 Egon Elbre 2017-05-10 10:49:45 UTC
(In reply to Nick Clifton from comment #3)
> Created attachment 10044 [details]
> Linker script fragment
> 
> Hi Egon,
> 
> > But, it does look like it's using new linker and doesn't create a valid 
> > executable. Will investigate further.
> 
> Darn!  I assume that the problem is still the same - ie the
> .debug_gdb_scripts section is still being placed at VMA 0 ?

I've confirmed that it reaches `place = &hold[orphan_debug]` and it uses new `ld`.

VMA is not zero... it's 1 << 32.

Using section `.debug_gdb_scripts`

$ objdump -h a.exe

a.exe:     file format pei-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .debug_gdb_scripts 00000010  0000000100000000  0000000100000000  00000480  2**3
                  CONTENTS, READONLY, DEBUGGING
  1 .debug_abbrev 00002507  0000000100001000  0000000100001000  00000680  2**0
                  CONTENTS, READONLY, DEBUGGING
  2 .debug_line   00002b24  0000000100004000  0000000100004000  00002c80  2**0
                  CONTENTS, READONLY, DEBUGGING
  3 .debug_frame  00000a00  0000000100007000  0000000100007000  00005880  2**3
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_str    000007c6  0000000100008000  0000000100008000  00006280  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_loc    00002bb4  0000000100009000  0000000100009000  00006a80  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_ranges 00000560  000000010000c000  000000010000c000  00009680  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .text         00001da8  0000000000401000  0000000000401000  00009e00  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
  8 .data         000000a8  0000000000403000  0000000000403000  0000bc00  2**4
                  CONTENTS, ALLOC, LOAD, DATA
  9 .rdata        000009a0  0000000000404000  0000000000404000  0000be00  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .pdata        00000264  0000000000405000  0000000000405000  0000c800  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 11 .xdata        00000208  0000000000406000  0000000000406000  0000cc00  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 12 .bss          00000990  0000000000407000  0000000000407000  00000000  2**5
                  ALLOC
 13 .idata        000007f8  0000000000408000  0000000000408000  0000d000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 14 .CRT          00000068  0000000000409000  0000000000409000  0000d800  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 15 .tls          00000068  000000000040a000  000000000040a000  0000da00  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 16 .rsrc         000004e8  000000000040b000  000000000040b000  0000dc00  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .debug_aranges 000003d0  000000000040c000  000000000040c000  0000e200  2**0
                  CONTENTS, READONLY, DEBUGGING
 18 .debug_info   00048ae3  000000000040d000  000000000040d000  0000e600  2**0
                  CONTENTS, READONLY, DEBUGGING

When using section `.xxxxx_gdb_scripts` the executable works and gives this result (maybe this helps):

a.exe:     file format pei-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00001da8  0000000000401000  0000000000401000  00000600  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
  1 .data         000000a8  0000000000403000  0000000000403000  00002400  2**4
                  CONTENTS, ALLOC, LOAD, DATA
  2 .xxxxx_gdb_scripts 00000010  0000000000404000  0000000000404000  00002600  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  3 .rdata        000009a0  0000000000405000  0000000000405000  00002800  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .pdata        00000264  0000000000406000  0000000000406000  00003200  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .xdata        00000208  0000000000407000  0000000000407000  00003600  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .bss          00000990  0000000000408000  0000000000408000  00000000  2**5
                  ALLOC
  7 .idata        000007f8  0000000000409000  0000000000409000  00003a00  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  8 .CRT          00000068  000000000040a000  000000000040a000  00004200  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  9 .tls          00000068  000000000040b000  000000000040b000  00004400  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 10 .rsrc         000004e8  000000000040c000  000000000040c000  00004600  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 11 .debug_aranges 000003d0  000000000040d000  000000000040d000  00004c00  2**0
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_info   00048ae3  000000000040e000  000000000040e000  00005000  2**0
                  CONTENTS, READONLY, DEBUGGING
 13 .debug_abbrev 00002507  0000000000457000  0000000000457000  0004dc00  2**0
                  CONTENTS, READONLY, DEBUGGING
 14 .debug_line   00002b24  000000000045a000  000000000045a000  00050200  2**0
                  CONTENTS, READONLY, DEBUGGING
 15 .debug_frame  00000a00  000000000045d000  000000000045d000  00052e00  2**3
                  CONTENTS, READONLY, DEBUGGING
 16 .debug_str    000007c6  000000000045e000  000000000045e000  00053800  2**0
                  CONTENTS, READONLY, DEBUGGING
 17 .debug_loc    00002bb4  000000000045f000  000000000045f000  00054000  2**0
                  CONTENTS, READONLY, DEBUGGING
 18 .debug_ranges 00000560  0000000000462000  0000000000462000  00056c00  2**0
                  CONTENTS, READONLY, DEBUGGING

> 
> > A quick question,
> 
> > Is there a workaround to coerce the unfixed ld to behave similarly via 
> > command-line flags or some config script?
> 
> Actually, yes there is. :-)  Have a look at the attached linker script
> fragment.
> It tells the linker exactly where it should place the .debug_gdb_scripts
> section.  You can use this fragment to augment the already existing,
> built-in, linker script by using this on your linker command line:
> 
>   -T debug.ld
> 
> or if you are using gcc or g++:
> 
>   -Wl,-T,debug.ld
> 
> Now this fix will only work for the .debug_gdb_scripts section, but you can
> easily edit the debug.ld file and add in other problematic sections as you
> wish.

Awesome!

Thank you very much. I think this should help fix a bug in Go and Rust at 
the same time. :D

> 
> You may ask, "why not just add these sections to the built-in linker script
> ?".  We could - but - that would only solve the problem for those specific
> sections.  The patch that I created is intended to work for any .debug_xxx
> section, regardless of its name.
> 
> Cheers
>   Nick
Comment 5 Nick Clifton 2017-05-11 13:14:01 UTC
Created attachment 10046 [details]
Proposed patch

Updated version of previous patch.  Not sure that it will fix the problem of the excessively large VMA value though.
Comment 6 Egon Elbre 2017-05-11 15:45:00 UTC
(In reply to Nick Clifton from comment #5)
> Created attachment 10046 [details]
> Proposed patch
> 
> Updated version of previous patch.  Not sure that it will fix the problem of
> the excessively large VMA value though.

Unfortunately no, still there.

I have a hypothesis: maybe there is a cast of uint32_t(-1), which then gets aligned as uint64_t to give result 100000000LL.

Btw. is there any debug output or any other printf that would be helpful to you?
Comment 7 Nick Clifton 2017-05-12 11:02:34 UTC
Hi Egon,

(In reply to Egon Elbre from comment #6)
> Btw. is there any debug output or any other printf that would be helpful to
> you?

No - I can reproduce the problem myself.  I just do not have any way of checking whether the binaries produced actually work or not.  Ie I do not have a test environment.

I am wondering whether it would be better to just take the easy way out and add .debug_gdb_scripts to the pe and pep linker scripts.  Do you know if there are any other .debug_xxx sections that might also be generated for go binaries ?

Cheers
  Nick
Comment 8 Egon Elbre 2017-05-12 16:14:03 UTC
(In reply to Nick Clifton from comment #7)
> Hi Egon,
> 
> (In reply to Egon Elbre from comment #6)
> > Btw. is there any debug output or any other printf that would be helpful to
> > you?
> 
> No - I can reproduce the problem myself.  I just do not have any way of
> checking whether the binaries produced actually work or not.  Ie I do not
> have a test environment.

I'm wondering whether Wine or ReactOS will fail with that executable?

Do you see the same result with objdump? I guess the VMA should be near the other sections and when it's not, then it could be considered as broken -- maybe?

> 
> I am wondering whether it would be better to just take the easy way out and
> add .debug_gdb_scripts to the pe and pep linker scripts.  Do you know if
> there are any other .debug_xxx sections that might also be generated for go
> binaries ?

Go - initial searching came up only with:

.debug_abbrev
.debug_aranges
.debug_info
.debug_line
.debug_pubnames
.debug_ranges
.debug_str

Sure, if it seems too much work it's fine to include in the script.

Maybe there's a good place to put an ASSERT bomb when it tries to write VMA > 0xFFFFFFFFLL or zero?

> 
> Cheers
>   Nick
Comment 9 Sourceware Commits 2017-05-15 12:13:54 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=786e3eba7915df35df1d98a300e06f757336c75b

commit 786e3eba7915df35df1d98a300e06f757336c75b
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon May 15 13:12:49 2017 +0100

    Add .debug_gdb_scripts section to PE linker scripts.
    
    	PR ld/21459
    	* scripttempl/pe.sc: Add .debug_gdb_scripts section.
    	* scripttempl/pep.sc: Likewise.
Comment 10 Nick Clifton 2017-05-15 12:21:30 UTC
Hi Egon,

(In reply to Egon Elbre from comment #8)

> I'm wondering whether Wine or ReactOS will fail with that executable?

Maybe - I could also set up a proper MinGW or Cygwin environment.  The
real problem is time - I just do not have enough of it to spend on these
bugs. :-(

> Do you see the same result with objdump?

Oh yes - I just thought that the non-zero VMA value would be enough.  I did
not know that there was going to be a problem with large gaps between parts
of the program and/or excessively large VMA values.

> Sure, if it seems too much work it's fine to include in the script.

I have gone ahead and done that.  It is a simple, easy fix that will let you
get on with your work for now.

> Maybe there's a good place to put an ASSERT bomb when it tries to write VMA
> 0xFFFFFFFFLL or zero?

Probably.  Although I would love to know if it is the high VMA address that is causing the problem, or the gap between the two parts of the program that is causing the problem.  (We are talking 64-bit binaries here, right ?)

Anyway, I will leave this PR open, but I am not expecting to be able to give it a lot of time unless it becomes a real show-stopper for someone.

Cheers
  Nick
Comment 11 Egon Elbre 2017-05-15 13:42:20 UTC
(In reply to Nick Clifton from comment #10)
> Hi Egon,
> 
> (In reply to Egon Elbre from comment #8)
> 
> > I'm wondering whether Wine or ReactOS will fail with that executable?
> 
> Maybe - I could also set up a proper MinGW or Cygwin environment.  The
> real problem is time - I just do not have enough of it to spend on these
> bugs. :-(

Sure, I understand.

> 
> > Do you see the same result with objdump?
> 
> Oh yes - I just thought that the non-zero VMA value would be enough.  I did
> not know that there was going to be a problem with large gaps between parts
> of the program and/or excessively large VMA values.
> 
> > Sure, if it seems too much work it's fine to include in the script.
> 
> I have gone ahead and done that.  It is a simple, easy fix that will let you
> get on with your work for now.
> 
> > Maybe there's a good place to put an ASSERT bomb when it tries to write VMA
> > 0xFFFFFFFFLL or zero?
> 
> Probably.  Although I would love to know if it is the high VMA address that
> is causing the problem, or the gap between the two parts of the program that
> is causing the problem.  (We are talking 64-bit binaries here, right ?)

After testing some more it seems that when you set the VMA=0x0, then objdump will show it as 0x100000000. I'm not sure whether it's intentional (per spec) or not (an underflow).

After searching about gap issues in PE, I found these:

https://github.com/msekletar/sbsigntool/blob/a6043253a4f8621b8eac0fd099e26a8a992cb13a/src/image.c#L331

https://stackoverflow.com/questions/32378033/why-does-section-virtual-addresses-need-to-be-continuous

Few links later I found PE/Coff spec, which says:

  In an image file, the VAs for sections must be assigned by the 
  linker so that they are in ascending order and adjacent, and 
  they must be a multiple of the SectionAlignment value in the 
  optional header.

and also...

  In an image file, the section data must be aligned on a boundary 
  as specified by the FileAlignment field in the optional header. 
  Section data must appear in order of the RVA values for the 
  corresponding sections (as do the individual section headers 
  in the section table).

And after ensuring that sections are adjacent, executable manages to start.

Cheers
  Egon

> 
> Anyway, I will leave this PR open, but I am not expecting to be able to give
> it a lot of time unless it becomes a real show-stopper for someone.
> 
> Cheers
>   Nick