My original post was rejected by LKML. Resend. On Mon, Dec 9, 2013 at 4:41 PM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Mon, Dec 9, 2013 at 4:37 PM, H. Peter Anvin <h...@zytor.com> wrote: >> On 12/09/2013 03:53 PM, H.J. Lu wrote: >>>>> >>>>> x86-64 small model is limited to 4GB in size. You can't build >>>>> a dynamic executable in small model larger than 4GB. >>>>> >>>>> There are medium and large models. But they are slower than >>>>> small models as well as small models in PIE. Also there are >>>>> no glibc run-times for medium and large models. >>>>> >>>> Compiling for the small PIC model shouldn't automatically mean >>>> generating a PIE (ET_DYN) executable, though (and if those are >>>> inherently linked, that is a fundamental bug IMNSHO.) >>> >>> PIE uses PIC. But GCC has -fPIE and -fPIC. They aren't >>> the same. You build PIE with >>> >>> 1. Compile with -fPIE. >>> 2. Link with -pie. >>> >> >> I'm talking about the memory model ("small PIC model"). I don't see why >> it should be encapsulated in a PIE (ET_DYN) container if the user >> doesn't want it to be relocatable. >> > > I see. Maybe linker can set ET_EXEC if vaddr is non-zero. >
Hi, Linker sets e_type in ELF header to ET_DYN for -pie -Ttext-segment=0xXXX. When I added -Ttext-segment=0xXXX, one goal was to load small model executable above 4GB on Linux/x86-64, which was done with -pie -Ttext-segment=0xXXX. But -pie sets e_type in ELF header to ET_DYN and kernel may ignore p_vaddr in ELF header to load ET_DYN binary at a random address. This patch changes ld to set e_type in ELF header to ET_EXEC if the first PT_LOAD segment has non-zero p_vaddr. If this is unacceptable as generic ELF change, I can make it specific to x86. Thanks. -- H.J. -- diff --git a/bfd/elf.c b/bfd/elf.c index 8df38ee..5862460 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -5152,6 +5152,27 @@ assign_file_positions_except_relocs (bfd *abfd, return FALSE; } + if (link_info != NULL + && link_info->executable + && link_info->shared) + { + Elf_Internal_Phdr *segment; + unsigned int i; + unsigned int num_segments = elf_elfheader (abfd)->e_phnum; + bfd_vma p_vaddr = 0; + for (i = 0, segment = elf_tdata (abfd)->phdr; + i < num_segments; + i++, segment++) + if (segment->p_type == PT_LOAD) + { + p_vaddr = segment->p_vaddr; + break; + } + + if (p_vaddr) + i_ehdrp->e_type = ET_EXEC; + } + /* Write out the program headers. */ alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr; if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0 -- H.J. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/