Bug 18201 - Incorrect ELF generated when .text is below 0x200000
Summary: Incorrect ELF generated when .text is below 0x200000
Status: RESOLVED INVALID
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-04-04 21:10 UTC by Biju Abraham
Modified: 2015-04-06 13:29 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
A patch (323 bytes, patch)
2015-04-05 19:43 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Biju Abraham 2015-04-04 21:10:57 UTC
OS: Ubuntu 14.04, Fedora 21
ARCH : x86_64

Perform steps below to generate the incorrect ELF.

$ cat test.c 
int main()
{
int x = 3;
/* do something */
asm volatile("mov $60,%rax; mov $0,%rbx; syscall");
}


$ cat mylinker.lds 
SECTIONS
{
   . = 0x100000;
   .text : { *(.text) }
   . = 0x8000000;
   .data : { *(.data) }
   .bss : { *(.bss) }
}

$ gcc -c test.c
$ ld -T mylinker.lds test.o -o test

$ readelf -l test

Elf file type is EXEC (Executable file)
Entry point 0x100000
There are 2 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000100060 0x0000000000100060  R E    200000
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10

Expected output :
  LOAD           0x0000000000100000 0x0000000000100000 0x0000000000000000
                 0x0000000000000060 0x0000000000000060  R E    200000


$ ./test
Killed

(Address 0 cannot be used by unprevileged users because of Linux kernel's  mmap_min_addr)

Manually fixing up the ELF file using hex editor or some utilty resolves the issue.

$ git clone https://github.com/bjxt/elf_fixup
$ cd elf_fixup
$ ./fixelf -e test -o 0x100000 -f 0x60 -v 0x100000 -m 0x60
$ ./test

Program completes successfully.
Comment 1 H.J. Lu 2015-04-05 19:43:29 UTC
Created attachment 8226 [details]
A patch

This patch works for me.
Comment 2 Alan Modra 2015-04-06 08:46:52 UTC
The resulting binary is not "incorrect ELF".  The fact that it won't run on Linux is simply due to invalid user input.

Something like HJ's patch might be OK if
a) it did not affect generic ELF targets
b) the minpagesize test was removed
c) info->shared test was replaced with abfd->flags & DYNAMIC, and ld modified to set output flags earlier, so that objcopy would make the same decisions as ld when rewriting headers.

Point (a) is because not loading the file and program headers just because the executable starts in the first page is only appropriate if the operating system unmaps the first page.  However, implementing (a) is tricky, not least because more than one Linux target is no different from the generic ELF target for that architecture..

So I'm going to close the bug as invalid.  Starting an executable in the first page is just one of many ways a user can break things with custom linker scripts, or with -Ttext.
Comment 3 H.J. Lu 2015-04-06 13:29:47 UTC
You can use -z max-page-size=0x1000 to work around it.