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.
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
(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
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
(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
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.
(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?
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
(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
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.
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
(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