Any version of valgrind (I tried 3.4.1, current svn, and some older svn revs before I figured this out) fails with a message like valgrind: mmap(0x8048000, 90112) failed in UME with error 22 (Invalid argument). valgrind: this can be caused by executables with very large text, data or bss segments. if valgrind was linked using gold instead of ld. This happens very quickly, before any other output, and happens even with --tool=none. No other output is shown even with -v. Easiest way with recent debian or Ubuntu Koala is "sudo apt-get install binutils-gold". On older systems, you have to build gold yourself. I'll attach an easy script that builds gold and installs it as the system linker (and renames the old linker to ld.orig).
Created attachment 33872 [details] Minimally disruptive script to build and install gold
This was with gold built from the binutils-2.19.1 source tarball.
Err, maybe our top level linker script screwed up somehow, and so our executables are linked with the text segment being in the wrong place. It should be at 0x38000000. What sayeth readelf -l .../memcheck-amd64-linux ? Anyway .. if gold can't link a program which older binutils links without difficulty, isn't that a bug in gold?
$ readelf -l valgrind-3.4.1*/memcheck/memcheck-x86-linux File: valgrind-3.4.1.gold/memcheck/memcheck-x86-linux Elf file type is EXEC (Executable file) Entry point 0x80709d0 There are 3 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x08048000 0x08048000 0x1b9df8 0x1b9df8 R E 0x1000 LOAD 0x1ba000 0x08202000 0x08202000 0x005a0 0x71e848 RW 0x1000 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0 Section to Segment mapping: Segment Sections... 00 .text .rodata .eh_frame 01 .data .bss 02 File: valgrind-3.4.1/memcheck/memcheck-x86-linux Elf file type is EXEC (Executable file) Entry point 0x380289d0 There are 3 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x38000000 0x38000000 0x1b8238 0x1b8238 R E 0x1000 LOAD 0x1b8240 0x381b9240 0x381b9240 0x005a0 0x71e860 RW 0x1000 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 Section to Segment mapping: Segment Sections... 00 .text .rodata .eh_frame 01 .data .bss 02 The program links just fine. It just doesn't run :-) I did file an FYI bug against gold, http://sourceware.org/bugzilla/show_bug.cgi?id=10178 but if it's a gold bug, they will probably need some analysis from a valgrind developer to show them where they screwed up.
Yep, gold ignored our request to put the text segment at 0x38000000: w/gold LOAD 0x000000 0x08048000 0x08048000 0x1b9df8 0x1b9df8 R E 0x1000 w/std binutils LOAD 0x000000 0x38000000 0x38000000 0x1b8238 0x1b8238 R E 0x1000 Result is, V is linked at the default address (0x8048000) and so when it comes to load the executable to be run, which also wants to be at 0x8048000, it can't. So it just gives up, which is what you saw. Next step is to figure out why gold doesn't like our linker script, valt_load_address_x86_linux.lds. Funny thing is though, I'm sure I remember trying gold on V some time last year, and it worked fine.
In http://sourceware.org/bugzilla/show_bug.cgi?id=10178#c2 Ian (the author of both ld and gold) said "The core issue is that valgrind runs the linker with --verbose to extract the linker script. It then seds the linker script to adjust the start address of the text segment. This works OK with the GNU linker, but it fails with gold, since gold does not have a default linker script. With gold it ought to work to simply use the -Ttext option. In any case, gold will never have a default linker script, so this is not something that can be fixed in gold." So I guess the ball is in valgrind's court.
I took a look at building valgrind 3.4.1 with gold. The valgrind build works by running the linker with the --verbose option to extract the linker script. It then edits the linker script to set the address of the start of the text segment. This approach works with the GNU linker, but it will never work with gold, as gold does not have a default linker script. With gold it will almost certainly work to simply link with a -Ttext option specifying where you want the text segment to start. No linker script should be necessary if that is all you need to do.
I think I have a plan to fix this. Can anyone tell me what an easy way to try out gold is, without trashing/rebuilding my existing tool chain? That's what I need to know to get started.
Here is one approach. After you download the GNU binutils, built gold using mkdir objdir cd objdir ../binutilssrc/configure --enable-gold --prefix=/my/private/installdir make all-gold make install-gold That will give you a binary /my/private/installdir/bin/ld. Temporarily put that bin directory first on your PATH. Make sure that when valgrind is built it uses that ld rather than the default one.
(In reply to comment #9) > That will give you a binary /my/private/installdir/bin/ld. Temporarily put > that bin directory first on your PATH. Make sure that when valgrind is built > it uses that ld rather than the default one. This doesn't work, alas. I can build gold OK: $ ld --version GNU gold (GNU Binutils 2.20.1.20100303) 1.9 but the distro gcc still links using /usr/lib64/gcc/x86_64-suse-linux/4.3/collect2 Is there a way to tell gcc to use a different linker? -Bsomething ?
But there's something broader I don't understand. It appears that (at least according to ld --help) both gold and the old linker understand "-Ttext". So if the old linker understands -Ttext, why are we arsing around with linker scripts and sed? -Ttext should work for both old and new linkers.
FWIW, linking using the old linker, no linker script, and simply -Wl,-Ttext=0x38000000 gives a tool executable that works just fine. Urr. And passing the same command line to gold as is passed to collect2 also produces a working executable. So -- unless there's a good reason not to do so -- I propose to simply nuke the linker scripts, and use -Ttext, and that should Just Work (tm).
Created attachment 47498 [details] proposed fix Here's a proposed fix. I think it should work with gold but as per comments above I so far have been unable to get gcc to run gold. Can someone with a gold-enabled system please try it?
gcc always uses the collect2 driver program to link. That is true whether you are using GNU ld or gold. To see which linker the collect2 driver runs, use -Wl,-debug when you link.
Fixed, r11141. Although as per comments above, have been unable to test this with gold. Closing. If it still doesn't work with gold, please re-open.
Looks like this is still reproducible in r11144 for me. I can submit the build log, if necessary.
Is that with a clean (eg, from distclean) build? This fix involves messing with the build system, so from-scratch build is really necessary.
(In reply to comment #16) Yes, confirming that linking on 64-bit Ubuntu 10.04 also produces a non-working Valgrind. This despite 10.04 using traditional ld. This happens because ld-2.20.1 (on Ubuntu 10.04) inserts an extra loadable r-- segment which is mapped at the default load address (0x400000) despite -Ttext=0x38000000 being specified (and honoured) for text: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align ** THIS ONE ** LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x00000000000001b4 0x00000000000001b4 R 200000 LOAD 0x0000000000200000 0x0000000038000000 0x0000000038000000 0x00000000001cad88 0x00000000001cad88 R E 200000 LOAD 0x00000000003cafd0 0x00000000383cafd0 0x00000000383cafd0 0x0000000000001bf0 0x00000000009812b0 RW 200000 NOTE 0x0000000000000190 0x0000000000400190 0x0000000000400190 0x0000000000000024 0x0000000000000024 R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 8 GNU_RELRO 0x00000000003cafd0 0x00000000383cafd0 0x00000000383cafd0 0x0000000000000030 0x0000000000000030 R 1 The older ld-2.18.50.20080409-11.1 (openSUSE 11.0) on which I developed this patch did not do that, and so it works fine: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000200000 0x0000000038000000 0x0000000038000000 0x00000000001d6928 0x00000000001d6928 R E 200000 LOAD 0x00000000003d6fd0 0x00000000383d6fd0 0x00000000383d6fd0 0x0000000000001bb0 0x0000000000981270 RW 200000 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 8 GNU_RELRO 0x00000000003d6fd0 0x00000000383d6fd0 0x00000000383d6fd0 0x0000000000000030 0x0000000000000030 R 1 Ian, is there any surefire way to get ld to map *all* loadable sections at an address at or above that specified by -Ttext ? FWIW we never had this problems when using linker scripts to specify an alternative load address.
You could try using -Ttext-segment instead of -Ttext with GNU ld. -Ttext should work reliably with gold. Unfortunately, gold does not currently have a -Ttext-segment option.
> Unfortunately, gold does not currently have a -Ttext-segment option. Neither do older versions of ld (2.18), it seems. --build-id=none seems a better bet.
(In reply to comment #16) > Looks like this is still reproducible in r11144 for me. Alexander, svn up (r11146 or later) and try again.
The problem has gon for me in r11146. I'm using gold 1.9 (binutils 2.20)