Bug 512822: "Launch failed. Binary not found" even after building

Builds upon https://git.eclipse.org/r/#/c/92129/ but also uses the hints
to only read the file if necessary. I further reverted some of
the changes done with the patch for 'Bug 510987 - Properly support PIE
executables as build output' since the binary will now be seen as an
executable anyway.

Change-Id: I075fef67f3b101ddbc64786dcbc2ca41cc114e25
Signed-off-by: Hansruedi Patzen <hansruedi.patzen@hsr.ch>
diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/elf/ElfParserTest.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/elf/ElfParserTest.java
new file mode 100644
index 0000000..0dcb030
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/utils/elf/ElfParserTest.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
+ * Rapperswil, University of applied sciences and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Hansruedi Patzen (IFS) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.utils.elf;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.utils.elf.parser.ElfBinaryExecutable;
+import org.eclipse.cdt.utils.elf.parser.ElfBinaryShared;
+import org.eclipse.cdt.utils.elf.parser.ElfParser;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class ElfParserTest extends TestCase {
+
+	ElfParser elfParser;
+
+	public static Test suite() {
+		return new TestSuite(ElfParserTest.class);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		elfParser = new ElfParser();
+		super.setUp();
+	}
+
+	private byte[] readHints(final IPath path) throws IOException {
+		int bytesToRead = elfParser.getHintBufferSize();
+		byte[] hints = new byte[bytesToRead];
+		try (FileInputStream is = new FileInputStream(path.toFile())) {
+			is.read(hints);
+		}
+		return hints;
+	}
+
+	/*
+	 * The most probable cause for failing one of the following tests
+	 * 
+	 * testLE64DYNwithInterpELFoutsideHintsError_Bug512822
+	 * testLE32DYNwithInterpELFoutsideHintsError_Bug512822
+	 * 
+	 * is that the hint buffer size has been changed and the test binaries
+	 * are too small and need to be updated to reflect this change as well.
+	 * 
+	 * The original files have been manually created using nasm. See the
+	 * *.asm files inside resources/elf/{inside_hints,outside_hints}/ for
+	 * further details.
+	 */
+	public void testLE64DYNwithInterpELFoutsideHintsError_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/le64");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertFalse("Binary should not be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testLE32DYNwithInterpELFoutsideHintsError_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/le32");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertFalse("Binary should not be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testLE64DYNwithInterpELFinsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/inside_hints/le64");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertTrue("Binary should be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testLE32DYNwithInterpELFinsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/inside_hints/le32");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertTrue("Binary should be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testLE64DYNwithInterpELFoutsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/le64");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), path);
+		assertTrue("Binary should be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testLE32DYNwithInterpELFoutsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/le32");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), path);
+		assertTrue("Binary should be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testLE32DYNnoInterpELFinsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/inside_hints/le32lib");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertTrue("Binary should be a library", binary instanceof ElfBinaryShared);
+	}
+
+	public void testLE64DYNnoInterpELFinsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/inside_hints/le64lib");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertTrue("Binary should be a library", binary instanceof ElfBinaryShared);
+	}
+
+	public void testLE32DYNnoInterpELFoutsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/le32lib");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), path);
+		assertTrue("Binary should be a library", binary instanceof ElfBinaryShared);
+	}
+
+	public void testLE64DYNnoInterpELFoutsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/le64lib");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), path);
+		assertTrue("Binary should be a library", binary instanceof ElfBinaryShared);
+	}
+
+	public void testBE64DYNwithInterpELFinsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/inside_hints/be64");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertTrue("Binary should be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testBE32DYNwithInterpELFinsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/inside_hints/be32");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertTrue("Binary should be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testBE64DYNwithInterpELFoutsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/be64");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), path);
+		assertTrue("Binary should be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testBE32DYNwithInterpELFoutsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/be32");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), path);
+		assertTrue("Binary should be an executable", binary instanceof ElfBinaryExecutable);
+	}
+
+	public void testBE32DYNnoInterpELFinsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/inside_hints/be32lib");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertTrue("Binary should be a library", binary instanceof ElfBinaryShared);
+	}
+
+	public void testBE64DYNnoInterpELFinsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/inside_hints/be64lib");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), new Path(""));
+		assertTrue("Binary should be a library", binary instanceof ElfBinaryShared);
+	}
+
+	public void testBE32DYNnoInterpELFoutsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/be32lib");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), path);
+		assertTrue("Binary should be a library", binary instanceof ElfBinaryShared);
+	}
+
+	public void testBE64DYNnoInterpELFoutsideHints_Bug512822() throws CModelException, IOException {
+		IPath path = new Path("resources/elf/outside_hints/be64lib");
+		IBinaryFile binary = elfParser.getBinary(readHints(path), path);
+		assertTrue("Binary should be a library", binary instanceof ElfBinaryShared);
+	}
+}
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/Makefile b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/Makefile
new file mode 100644
index 0000000..215ec1c
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/Makefile
@@ -0,0 +1,28 @@
+all:	be32 be32lib be64 be64lib le32 le32lib le64 le64lib
+
+be32:	be32.asm
+	nasm be32.asm
+
+be32lib:	be32lib.asm
+	nasm be32lib.asm
+
+be64:	be64.asm
+	nasm be64.asm
+
+be64lib:	be64lib.asm
+	nasm be64lib.asm
+
+le32:	le32.asm
+	nasm le32.asm
+
+le32lib:	le32lib.asm
+	nasm le32lib.asm
+
+le64:	le64.asm
+	nasm le64.asm
+
+le64lib:	le64lib.asm
+	nasm le64lib.asm
+
+clean:
+	rm -f be32 be32lib be64 be64lib le32 le32lib le64 le64lib
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32 b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32
new file mode 100644
index 0000000..030133e
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32.asm b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32.asm
new file mode 100644
index 0000000..7caed30
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32.asm
@@ -0,0 +1,68 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x01; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x02; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0300; e_type: ET_DYN
+dw 0x0300; e_machine x86
+dd 0x01000000; e_version
+dd 0xC8000000; e_entry
+dd 0x34000000; e_phoff
+dd 0x00000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x3400; e_ehsize
+dw 0x2000; e_phentsize
+dw 0x0400; e_phnum
+dw 0x2800; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x06000000; p_type: PT_PHDR
+dd 0x34000000; p_offset
+dd 0x34000000; p_vaddr
+dd 0x34000000; p_paddr
+dd 0x60000000; p_filesz
+dd 0x60000000; p_memsz
+dd 0x04000000; p_flags, 32 bit
+dd 0x04000000; p_align
+
+; Program Header 2
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+; Program Header 3
+dd 0x03000000; p_type: PT_INTERP
+dd 0xB4000000; p_offset
+dd 0xB4000000; p_vaddr
+dd 0xB4000000; p_paddr
+dd 0x13000000; p_filesz
+dd 0x13000000; p_memsz
+dd 0x04000000; p_flags, 32 bit
+dd 0x01000000; p_align
+
+; Program Header 4
+dd 0x01000000; p_type: PT_LOAD
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0xB4000000; p_filesz
+dd 0xB4000000; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00010000; p_align
+
+db '/', 'l', 'i', 'b', '/', 'l', 'd', '-'
+db 'l', 'i', 'n', 'u', 'x', '.', 's', 'o'
+db '.', '2', 0x00
+db 0x00; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32lib b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32lib
new file mode 100644
index 0000000..cdb8cbd
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32lib
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32lib.asm b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32lib.asm
new file mode 100644
index 0000000..1e5e959
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be32lib.asm
@@ -0,0 +1,35 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x01; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x02; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0300; e_type: ET_DYN
+dw 0x0300; e_machine x86
+dd 0x01000000; e_version
+dd 0x58000000; e_entry
+dd 0x34000000; e_phoff
+dd 0x00000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x3400; e_ehsize
+dw 0x2000; e_phentsize
+dw 0x0100; e_phnum
+dw 0x2800; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+dd 0x03000000; random value
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64 b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64
new file mode 100644
index 0000000..f8b071a
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64.asm b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64.asm
new file mode 100644
index 0000000..860bedf
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64.asm
@@ -0,0 +1,60 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x02; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x02; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0300; e_type: ET_DYN
+dw 0x3E00; e_machine x86-64
+dd 0x01000000; e_version
+dq 0x1001000000000000; e_entry
+dq 0x4000000000000000; e_phoff
+dq 0x0000000000000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x4000; e_ehsize
+dw 0x3800; e_phentsize
+dw 0x0300; e_phnum
+dw 0x4000; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x06000000; p_type: PT_PHDR
+dd 0x04000000; p_flags, x86-64 only
+dq 0x4000000000000000; p_offset
+dq 0x4000000000000000; p_vaddr
+dq 0x4000000000000000; p_paddr
+dq 0xB000000000000000; p_filesz
+dq 0xB000000000000000; p_memsz
+dq 0x0800000000000000; p_align
+
+; Program Header 2
+dd 0x03000000; p_type: PT_INTERP
+dd 0x04000000; p_flags, x86-64 only
+dq 0xE800000000000000; p_offset
+dq 0xE800000000000000; p_vaddr
+dq 0xE800000000000000; p_paddr
+dq 0x1C00000000000000; p_filesz
+dq 0x1C00000000000000; p_memsz
+dq 0x0100000000000000; p_align
+
+; Program Header 3
+dd 0x01000000; p_type: PT_LOAD
+dd 0x04000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0xF000000000000000; p_filesz
+dq 0xF000000000000000; p_memsz
+dq 0x0001000000000000; p_align
+
+db '/', 'l', 'i', 'b', '6', '4', '/', 'l'
+db 'd', '-', 'l', 'i', 'n', 'u', 'x', '-'
+db 'x', '8', '6', '-', '6', '4', '.', 's'
+db 'o', '.', '2', 0x00
+dd 0x00; pad
+dq 0x00; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64lib b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64lib
new file mode 100644
index 0000000..d79a435
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64lib
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64lib.asm b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64lib.asm
new file mode 100644
index 0000000..c1d2cab
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/be64lib.asm
@@ -0,0 +1,36 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x02; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x02; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0300; e_type: ET_DYN
+dw 0x3E00; e_machine x86-64
+dd 0x01000000; e_version
+dq 0x8000000000000000; e_entry
+dq 0x4000000000000000; e_phoff
+dq 0x0000000000000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x4000; e_ehsize
+dw 0x3800; e_phentsize
+dw 0x0100; e_phnum
+dw 0x4000; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x0000000000000000; p_filesz
+dq 0x0000000000000000; p_memsz
+dq 0x0000000000000000; p_align
+
+dd 0x03000000; random value
+dd 0x00000000; pad;
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32 b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32
new file mode 100644
index 0000000..0c8c46b
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32.asm b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32.asm
new file mode 100644
index 0000000..f6c5c1f
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32.asm
@@ -0,0 +1,68 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x01; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x01; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0003; e_type: ET_DYN
+dw 0x0003; e_machine x86
+dd 0x00000001; e_version
+dd 0x000000C8; e_entry
+dd 0x00000034; e_phoff
+dd 0x00000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x0034; e_ehsize
+dw 0x0020; e_phentsize
+dw 0x0004; e_phnum
+dw 0x0028; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000006; p_type: PT_PHDR
+dd 0x00000034; p_offset
+dd 0x00000034; p_vaddr
+dd 0x00000034; p_paddr
+dd 0x00000060; p_filesz
+dd 0x00000060; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00000004; p_align
+
+; Program Header 2
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+; Program Header 3
+dd 0x00000003; p_type: PT_INTERP
+dd 0x000000B4; p_offset
+dd 0x000000B4; p_vaddr
+dd 0x000000B4; p_paddr
+dd 0x00000013; p_filesz
+dd 0x00000013; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00000001; p_align
+
+; Program Header 4
+dd 0x00000001; p_type: PT_LOAD
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x000000B4; p_filesz
+dd 0x000000B4; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00000100; p_align
+
+db '/', 'l', 'i', 'b', '/', 'l', 'd', '-'
+db 'l', 'i', 'n', 'u', 'x', '.', 's', 'o'
+db '.', '2', 0x00
+db 0x00; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32lib b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32lib
new file mode 100644
index 0000000..f290fe9
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32lib
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32lib.asm b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32lib.asm
new file mode 100644
index 0000000..d8801c4
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le32lib.asm
@@ -0,0 +1,35 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x01; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x01; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0003; e_type: ET_DYN
+dw 0x0003; e_machine x86
+dd 0x00000001; e_version
+dd 0x00000058; e_entry
+dd 0x00000034; e_phoff
+dd 0x00000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x0034; e_ehsize
+dw 0x0020; e_phentsize
+dw 0x0001; e_phnum
+dw 0x0028; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+dd 0x00000003; random value
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64 b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64
new file mode 100644
index 0000000..882bd7e
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64.asm b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64.asm
new file mode 100644
index 0000000..2741ade
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64.asm
@@ -0,0 +1,60 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x02; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x01; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0003; e_type: ET_DYN
+dw 0x003E; e_machine x86-64
+dd 0x00000001; e_version
+dq 0x0000000000000110; e_entry
+dq 0x0000000000000040; e_phoff
+dq 0x0000000000000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x0040; e_ehsize
+dw 0x0038; e_phentsize
+dw 0x0003; e_phnum
+dw 0x0040; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000006; p_type: PT_PHDR
+dd 0x00000004; p_flags, x86-64 only
+dq 0x0000000000000040; p_offset
+dq 0x0000000000000040; p_vaddr
+dq 0x0000000000000040; p_paddr
+dq 0x00000000000000B0; p_filesz
+dq 0x00000000000000B0; p_memsz
+dq 0x0000000000000008; p_align
+
+; Program Header 2
+dd 0x00000003; p_type: PT_INTERP
+dd 0x00000004; p_flags, x86-64 only
+dq 0x00000000000000E8; p_offset
+dq 0x00000000000000E8; p_vaddr
+dq 0x00000000000000E8; p_paddr
+dq 0x000000000000001C; p_filesz
+dq 0x000000000000001C; p_memsz
+dq 0x0000000000000001; p_align
+
+; Program Header 3
+dd 0x00000001; p_type: PT_LOAD
+dd 0x00000004; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x00000000000000F0; p_filesz
+dq 0x00000000000000F0; p_memsz
+dq 0x0000000000000100; p_align
+
+db '/', 'l', 'i', 'b', '6', '4', '/', 'l'
+db 'd', '-', 'l', 'i', 'n', 'u', 'x', '-'
+db 'x', '8', '6', '-', '6', '4', '.', 's'
+db 'o', '.', '2', 0x00
+dd 0x00; pad
+dq 0x00; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64lib b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64lib
new file mode 100644
index 0000000..de4071e
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64lib
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64lib.asm b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64lib.asm
new file mode 100644
index 0000000..af68aa5
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/inside_hints/le64lib.asm
@@ -0,0 +1,36 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x02; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x01; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0003; e_type: ET_DYN
+dw 0x003E; e_machine x86-64
+dd 0x00000001; e_version
+dq 0x0000000000000080; e_entry
+dq 0x0000000000000040; e_phoff
+dq 0x0000000000000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x0040; e_ehsize
+dw 0x0038; e_phentsize
+dw 0x0001; e_phnum
+dw 0x0040; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x0000000000000000; p_filesz
+dq 0x0000000000000000; p_memsz
+dq 0x0000000000000000; p_align
+
+dd 0x00000003; random value
+dd 0x00000000; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/Makefile b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/Makefile
new file mode 100644
index 0000000..215ec1c
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/Makefile
@@ -0,0 +1,28 @@
+all:	be32 be32lib be64 be64lib le32 le32lib le64 le64lib
+
+be32:	be32.asm
+	nasm be32.asm
+
+be32lib:	be32lib.asm
+	nasm be32lib.asm
+
+be64:	be64.asm
+	nasm be64.asm
+
+be64lib:	be64lib.asm
+	nasm be64lib.asm
+
+le32:	le32.asm
+	nasm le32.asm
+
+le32lib:	le32lib.asm
+	nasm le32lib.asm
+
+le64:	le64.asm
+	nasm le64.asm
+
+le64lib:	le64lib.asm
+	nasm le64lib.asm
+
+clean:
+	rm -f be32 be32lib be64 be64lib le32 le32lib le64 le64lib
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32 b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32
new file mode 100644
index 0000000..4b2d957
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32.asm b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32.asm
new file mode 100644
index 0000000..bc53c82
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32.asm
@@ -0,0 +1,68 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x01; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x02; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0300; e_type: ET_DYN
+dw 0x0300; e_machine x86
+dd 0x01000000; e_version
+dd 0xC8000000; e_entry
+dd 0x34000000; e_phoff
+dd 0x00000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x3400; e_ehsize
+dw 0x2000; e_phentsize
+dw 0x0400; e_phnum
+dw 0x2800; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x06000000; p_type: PT_PHDR
+dd 0x34000000; p_offset
+dd 0x34000000; p_vaddr
+dd 0x34000000; p_paddr
+dd 0x60000000; p_filesz
+dd 0x60000000; p_memsz
+dd 0x04000000; p_flags, 32 bit
+dd 0x04000000; p_align
+
+; Program Header 2
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+; Program Header 3
+dd 0x01000000; p_type: PT_LOAD
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0xB4000000; p_filesz
+dd 0xB4000000; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00010000; p_align
+
+; Program Header 4
+dd 0x03000000; p_type: PT_INTERP
+dd 0xB4000000; p_offset
+dd 0xB4000000; p_vaddr
+dd 0xB4000000; p_paddr
+dd 0x13000000; p_filesz
+dd 0x13000000; p_memsz
+dd 0x04000000; p_flags, 32 bit
+dd 0x01000000; p_align
+
+db '/', 'l', 'i', 'b', '/', 'l', 'd', '-'
+db 'l', 'i', 'n', 'u', 'x', '.', 's', 'o'
+db '.', '2', 0x00
+db 0x00; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32lib b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32lib
new file mode 100644
index 0000000..71831ef
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32lib
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32lib.asm b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32lib.asm
new file mode 100644
index 0000000..7a9243c
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be32lib.asm
@@ -0,0 +1,65 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x01; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x02; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0300; e_type: ET_DYN
+dw 0x0300; e_machine x86
+dd 0x01000000; e_version
+dd 0xB8000000; e_entry
+dd 0x34000000; e_phoff
+dd 0x00000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x3400; e_ehsize
+dw 0x2000; e_phentsize
+dw 0x0400; e_phnum
+dw 0x2800; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x06000000; p_type: PT_PHDR
+dd 0x34000000; p_offset
+dd 0x34000000; p_vaddr
+dd 0x34000000; p_paddr
+dd 0x60000000; p_filesz
+dd 0x60000000; p_memsz
+dd 0x04000000; p_flags, 32 bit
+dd 0x04000000; p_align
+
+; Program Header 2
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+; Program Header 3
+dd 0x01000000; p_type: PT_LOAD
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0xB4000000; p_filesz
+dd 0xB4000000; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00010000; p_align
+
+; Program Header 4
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+dd 0x03000000; random value
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64 b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64
new file mode 100644
index 0000000..f583a24
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64.asm b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64.asm
new file mode 100644
index 0000000..77710a3
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64.asm
@@ -0,0 +1,60 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x02; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x02; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0300; e_type: ET_DYN
+dw 0x3E00; e_machine x86-64
+dd 0x01000000; e_version
+dq 0x1001000000000000; e_entry
+dq 0x4000000000000000; e_phoff
+dq 0x0000000000000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x4000; e_ehsize
+dw 0x3800; e_phentsize
+dw 0x0300; e_phnum
+dw 0x4000; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x06000000; p_type: PT_PHDR
+dd 0x04000000; p_flags, x86-64 only
+dq 0x4000000000000000; p_offset
+dq 0x4000000000000000; p_vaddr
+dq 0x4000000000000000; p_paddr
+dq 0xB000000000000000; p_filesz
+dq 0xB000000000000000; p_memsz
+dq 0x0800000000000000; p_align
+
+; Program Header 2
+dd 0x01000000; p_type: PT_LOAD
+dd 0x04000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0xF000000000000000; p_filesz
+dq 0xF000000000000000; p_memsz
+dq 0x0001000000000000; p_align
+
+; Program Header 3
+dd 0x03000000; p_type: PT_INTERP
+dd 0x04000000; p_flags, x86-64 only
+dq 0xE800000000000000; p_offset
+dq 0xE800000000000000; p_vaddr
+dq 0xE800000000000000; p_paddr
+dq 0x1C00000000000000; p_filesz
+dq 0x1C00000000000000; p_memsz
+dq 0x0100000000000000; p_align
+
+db '/', 'l', 'i', 'b', '6', '4', '/', 'l'
+db 'd', '-', 'l', 'i', 'n', 'u', 'x', '-'
+db 'x', '8', '6', '-', '6', '4', '.', 's'
+db 'o', '.', '2', 0x00
+dd 0x00; pad
+dq 0x00; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64lib b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64lib
new file mode 100644
index 0000000..eae3d51
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64lib
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64lib.asm b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64lib.asm
new file mode 100644
index 0000000..a0e881f
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/be64lib.asm
@@ -0,0 +1,56 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x02; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x02; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0300; e_type: ET_DYN
+dw 0x3E00; e_machine x86-64
+dd 0x01000000; e_version
+dq 0x1001000000000000; e_entry
+dq 0x4000000000000000; e_phoff
+dq 0x0000000000000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x4000; e_ehsize
+dw 0x3800; e_phentsize
+dw 0x0300; e_phnum
+dw 0x4000; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x0000000000000000; p_filesz
+dq 0x0000000000000000; p_memsz
+dq 0x0000000000000000; p_align
+
+; Program Header 2
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x0000000000000000; p_filesz
+dq 0x0000000000000000; p_memsz
+dq 0x0000000000000000; p_align
+
+; Program Header 3
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x0000000000000000; p_filesz
+dq 0x0000000000000000; p_memsz
+dq 0x0000000000000000; p_align
+
+dd 0x03000000; random value
+dd 0x00000000; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32 b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32
new file mode 100644
index 0000000..42a5f2b
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32.asm b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32.asm
new file mode 100644
index 0000000..c620e95
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32.asm
@@ -0,0 +1,68 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x01; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x01; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0003; e_type: ET_DYN
+dw 0x0003; e_machine x86
+dd 0x00000001; e_version
+dd 0x000000C8; e_entry
+dd 0x00000034; e_phoff
+dd 0x00000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x0034; e_ehsize
+dw 0x0020; e_phentsize
+dw 0x0004; e_phnum
+dw 0x0028; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000006; p_type: PT_PHDR
+dd 0x00000034; p_offset
+dd 0x00000034; p_vaddr
+dd 0x00000034; p_paddr
+dd 0x00000060; p_filesz
+dd 0x00000060; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00000004; p_align
+
+; Program Header 2
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+; Program Header 3
+dd 0x00000001; p_type: PT_LOAD
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x000000B4; p_filesz
+dd 0x000000B4; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00000100; p_align
+
+; Program Header 4
+dd 0x00000003; p_type: PT_INTERP
+dd 0x000000B4; p_offset
+dd 0x000000B4; p_vaddr
+dd 0x000000B4; p_paddr
+dd 0x00000013; p_filesz
+dd 0x00000013; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00000001; p_align
+
+db '/', 'l', 'i', 'b', '/', 'l', 'd', '-'
+db 'l', 'i', 'n', 'u', 'x', '.', 's', 'o'
+db '.', '2', 0x00
+db 0x00; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32lib b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32lib
new file mode 100644
index 0000000..bf77aea
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32lib
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32lib.asm b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32lib.asm
new file mode 100644
index 0000000..831a6ef
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le32lib.asm
@@ -0,0 +1,65 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x01; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x01; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0003; e_type: ET_DYN
+dw 0x0003; e_machine x86
+dd 0x00000001; e_version
+dd 0x000000B8; e_entry
+dd 0x00000034; e_phoff
+dd 0x00000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x0034; e_ehsize
+dw 0x0020; e_phentsize
+dw 0x0004; e_phnum
+dw 0x0028; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000006; p_type: PT_PHDR
+dd 0x00000034; p_offset
+dd 0x00000034; p_vaddr
+dd 0x00000034; p_paddr
+dd 0x00000060; p_filesz
+dd 0x00000060; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00000004; p_align
+
+; Program Header 2
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+; Program Header 3
+dd 0x00000001; p_type: PT_LOAD
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x000000B4; p_filesz
+dd 0x000000B4; p_memsz
+dd 0x00000004; p_flags, 32 bit
+dd 0x00000100; p_align
+
+; Program Header 4
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_offset
+dd 0x00000000; p_vaddr
+dd 0x00000000; p_paddr
+dd 0x00000000; p_filesz
+dd 0x00000000; p_memsz
+dd 0x00000000; p_flags, 32 bit
+dd 0x00000000; p_align
+
+dd 0x00000003; random value
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64 b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64
new file mode 100644
index 0000000..2185930
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64.asm b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64.asm
new file mode 100644
index 0000000..b13876a
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64.asm
@@ -0,0 +1,60 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x02; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x01; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0003; e_type: ET_DYN
+dw 0x003E; e_machine x86-64
+dd 0x00000001; e_version
+dq 0x0000000000000110; e_entry
+dq 0x0000000000000040; e_phoff
+dq 0x0000000000000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x0040; e_ehsize
+dw 0x0038; e_phentsize
+dw 0x0003; e_phnum
+dw 0x0040; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000006; p_type: PT_PHDR
+dd 0x00000004; p_flags, x86-64 only
+dq 0x0000000000000040; p_offset
+dq 0x0000000000000040; p_vaddr
+dq 0x0000000000000040; p_paddr
+dq 0x00000000000000B0; p_filesz
+dq 0x00000000000000B0; p_memsz
+dq 0x0000000000000008; p_align
+
+; Program Header 2
+dd 0x00000001; p_type: PT_LOAD
+dd 0x00000004; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x00000000000000F0; p_filesz
+dq 0x00000000000000F0; p_memsz
+dq 0x0000000000000100; p_align
+
+; Program Header 3
+dd 0x00000003; p_type: PT_INTERP
+dd 0x00000004; p_flags, x86-64 only
+dq 0x00000000000000E8; p_offset
+dq 0x00000000000000E8; p_vaddr
+dq 0x00000000000000E8; p_paddr
+dq 0x000000000000001C; p_filesz
+dq 0x000000000000001C; p_memsz
+dq 0x0000000000000001; p_align
+
+db '/', 'l', 'i', 'b', '6', '4', '/', 'l'
+db 'd', '-', 'l', 'i', 'n', 'u', 'x', '-'
+db 'x', '8', '6', '-', '6', '4', '.', 's'
+db 'o', '.', '2', 0x00
+dd 0x00; pad
+dq 0x00; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64lib b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64lib
new file mode 100644
index 0000000..4cd92f1
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64lib
Binary files differ
diff --git a/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64lib.asm b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64lib.asm
new file mode 100644
index 0000000..824a0d9
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/resources/elf/outside_hints/le64lib.asm
@@ -0,0 +1,56 @@
+; ELF Header
+db 0x7F, 'E', 'L', 'F'; Magic start
+db 0x02; EI_CLASS: 1: 32 bit, 2: 64 bit
+db 0x01; EI_DATA: 1: LE, 2: BE
+db 0x01; EI_VERSION: 1: Original ELF
+db 0x00; EI_OSABI: 00: System-V, 03: Linux, mostly 0x00 regardless
+db 0x00; EI_ABIVERSION: mostly unused therefore 0x00
+db 0x00; EI_PAD
+dw 0x0000; EI_PAD
+dd 0x00000000; EI_PAD
+dw 0x0003; e_type: ET_DYN
+dw 0x003E; e_machine x86-64
+dd 0x00000001; e_version
+dq 0x0000000000000110; e_entry
+dq 0x0000000000000040; e_phoff
+dq 0x0000000000000000; e_shoff
+dd 0x00000000; e_flags
+dw 0x0040; e_ehsize
+dw 0x0038; e_phentsize
+dw 0x0003; e_phnum
+dw 0x0040; e_shentsize
+dw 0x0000; e_shnum
+dw 0x0000; e_shstrndx
+
+; Program Header 1
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x0000000000000000; p_filesz
+dq 0x0000000000000000; p_memsz
+dq 0x0000000000000000; p_align
+
+; Program Header 2
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x0000000000000000; p_filesz
+dq 0x0000000000000000; p_memsz
+dq 0x0000000000000000; p_align
+
+; Program Header 3
+dd 0x00000000; p_type: PT_NULL
+dd 0x00000000; p_flags, x86-64 only
+dq 0x0000000000000000; p_offset
+dq 0x0000000000000000; p_vaddr
+dq 0x0000000000000000; p_paddr
+dq 0x0000000000000000; p_filesz
+dq 0x0000000000000000; p_memsz
+dq 0x0000000000000000; p_align
+
+dd 0x00000003; random value
+dd 0x00000000; pad
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java
index 74dd122..619803c 100644
--- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java
+++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java
@@ -38,6 +38,7 @@
 import org.eclipse.cdt.utils.StorableCdtVariablesTest;
 import org.eclipse.cdt.utils.UNCPathConverterTest;
 import org.eclipse.cdt.utils.WeakHashSetTest;
+import org.eclipse.cdt.utils.elf.ElfParserTest;
 
 import junit.framework.Test;
 import junit.framework.TestCase;
@@ -92,6 +93,7 @@
 		suite.addTest(ByteUtilsTest.suite());
 		suite.addTest(UNCPathConverterTest.suite());
 		suite.addTest(TestScopeOfBuildConfigResourceChangesPreference.suite());
+		suite.addTest(ElfParserTest.suite());
 
 		// Add in PDOM tests
 		suite.addTest(PDOMTests.suite());
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java
index e63c095..221f80b 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java
@@ -23,6 +23,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -32,7 +33,6 @@
 import java.util.regex.Pattern;
 
 import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.IBinaryParser;
 import org.eclipse.cdt.core.IConsoleParser;
 import org.eclipse.cdt.core.IConsoleParser2;
 import org.eclipse.cdt.core.IMarkerGenerator;
@@ -62,9 +62,6 @@
 import org.eclipse.cdt.internal.core.model.BinaryRunner;
 import org.eclipse.cdt.internal.core.model.CModelManager;
 import org.eclipse.cdt.internal.core.parser.ParserSettings2;
-import org.eclipse.cdt.utils.elf.Elf;
-import org.eclipse.cdt.utils.elf.Elf.PHdr;
-import org.eclipse.cdt.utils.elf.parser.ElfBinaryShared;
 import org.eclipse.core.filesystem.URIUtil;
 import org.eclipse.core.resources.IBuildConfiguration;
 import org.eclipse.core.resources.IContainer;
@@ -260,46 +257,22 @@
 		ICProject cproject = CoreModel.getDefault().create(config.getProject());
 		IBinaryContainer binaries = cproject.getBinaryContainer();
 		IPath outputPath = getBuildContainer().getFullPath();
-		List<IBinary> outputs = new ArrayList<>();
-		for (IBinary binary : binaries.getBinaries()) {
-			if (outputPath.isPrefixOf(binary.getPath())) {
-				if (binary.isExecutable()) {
-					outputs.add(binary);
-				} else if (binary.isSharedLib()) {
-					// Special case of PIE executable that looks like shared
-					// library
-					IBinaryParser.IBinaryObject bin = binary.getAdapter(IBinaryParser.IBinaryObject.class);
-					if (bin instanceof ElfBinaryShared) {
-						try {
-							Elf elf = new Elf(bin.getPath().toOSString());
-							for (PHdr phdr : elf.getPHdrs()) {
-								if (phdr.p_type == PHdr.PT_INTERP) {
-									outputs.add(binary);
-									break;
-								}
-							}
-						} catch (IOException e) {
-							CCorePlugin.log(e);
-						}
-					}
-				}
-			}
+		final IBinary[] outputs = getBuildOutput(binaries, outputPath);
+		if (outputs.length > 0) {
+			return outputs;
 		}
 
-		if (outputs.isEmpty()) {
-			// Give the binary runner a kick and try again.
-			BinaryRunner runner = CModelManager.getDefault().getBinaryRunner(cproject);
-			runner.start();
-			runner.waitIfRunning();
-			
-			for (IBinary binary : binaries.getBinaries()) {
-				if (binary.isExecutable() && outputPath.isPrefixOf(binary.getPath())) {
-					outputs.add(binary);
-				}
-			}
-		}
+		// Give the binary runner a kick and try again.
+		BinaryRunner runner = CModelManager.getDefault().getBinaryRunner(cproject);
+		runner.start();
+		runner.waitIfRunning();
+		return getBuildOutput(binaries, outputPath);
+	}
 
-		return outputs.toArray(new IBinary[outputs.size()]);
+	private IBinary[] getBuildOutput(final IBinaryContainer binaries, final IPath outputPath) throws CoreException {
+		return Arrays.stream(binaries.getBinaries())
+				.filter(b -> b.isExecutable() && outputPath.isPrefixOf(b.getPath()))
+				.toArray(IBinary[]::new);
 	}
 
 	public void setActive(IProgressMonitor monitor) throws CoreException {
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java
index 812b22e..80a38dd 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java
@@ -944,10 +944,8 @@
 	}
 
 	public static boolean isElfHeader(byte[] e_ident) {
-		if (e_ident.length < 4 || e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E'
-				|| e_ident[ELFhdr.EI_MAG2] != 'L' || e_ident[ELFhdr.EI_MAG3] != 'F')
-			return false;
-		return true;
+		return e_ident != null && e_ident.length >= 4 && e_ident[ELFhdr.EI_MAG0] == 0x7f
+				&& e_ident[ELFhdr.EI_MAG1] == 'E' && e_ident[ELFhdr.EI_MAG2] == 'L' && e_ident[ELFhdr.EI_MAG3] == 'F';
 	}
 
 	public void dispose() {
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java
index 108ed1b..65f1e2d 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java
@@ -8,11 +8,16 @@
  * Contributors:
  *     QNX Software Systems - Initial API and implementation
  *     Anton Leherbauer (Wind River Systems)
+ *     Hansruedi Patzen (IFS)
  *******************************************************************************/
 package org.eclipse.cdt.utils.elf.parser;
 
+import static org.eclipse.cdt.internal.core.ByteUtils.makeShort;
+import static org.eclipse.cdt.internal.core.ByteUtils.makeInt;
+
 import java.io.EOFException;
 import java.io.IOException;
+import java.util.Arrays;
 
 import org.eclipse.cdt.core.AbstractCExtension;
 import org.eclipse.cdt.core.CCorePlugin;
@@ -20,7 +25,10 @@
 import org.eclipse.cdt.utils.AR;
 import org.eclipse.cdt.utils.elf.Elf;
 import org.eclipse.cdt.utils.elf.Elf.Attribute;
+import org.eclipse.cdt.utils.elf.Elf.ELFhdr;
+import org.eclipse.cdt.utils.elf.Elf.PHdr;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
 
 /**
  */
@@ -46,19 +54,7 @@
 			binary = createBinaryArchive(path);
 		} else {
 			try {
-				Elf.Attribute attribute = null;
-				if (hints != null && Elf.isElfHeader(hints)) {
-					try {
-						attribute = Elf.getAttributes(hints);
-					} catch (EOFException eof) {
-						// continue, the array was to small.
-					}
-				}
-
-				//Take a second run at it if the data array failed.
-	 			if(attribute == null) {
-					attribute = Elf.getAttributes(path.toOSString());
-	 			}
+				Attribute attribute = getAttribute(hints, path);
 
 				if (attribute != null) {
 					switch (attribute.getType()) {
@@ -67,7 +63,7 @@
 							break;
 
 						case Attribute.ELF_TYPE_SHLIB :
-							binary = createBinaryShared(path);
+							binary = hasInterpProgramHeader(hints, path) ? createBinaryExecutable(path) : createBinaryShared(path);
 							break;
 
 						case Attribute.ELF_TYPE_OBJ :
@@ -139,4 +135,62 @@
 	protected IBinaryObject createBinaryCore(IPath path) throws IOException {
 		return new ElfBinaryObject(this, path, IBinaryFile.CORE);
 	}
+
+	private static Elf.Attribute getAttribute(byte[] hints, IPath path) throws IOException {
+		if (Elf.isElfHeader(hints)) {
+			try {
+				return Elf.getAttributes(hints);
+			} catch (EOFException eof) {
+				// continue, the array was to small.
+			}
+		}
+		return Elf.getAttributes(path.toOSString());
+	}
+
+	private static boolean hasInterpProgramHeader(byte[] hints, IPath path) throws IOException {
+		if (Elf.isElfHeader(hints)) {
+			int e_phentsizeOffset = 0;
+			int e_phnumOffset = 0;
+			int e_ehsizeOffset = 0;
+			switch (hints[ELFhdr.EI_CLASS]) {
+			case ELFhdr.ELFCLASS32:
+				e_ehsizeOffset = 0x28;
+				e_phentsizeOffset = 0x2A;
+				e_phnumOffset = 0x2C;
+				break;
+			case ELFhdr.ELFCLASS64:
+				e_ehsizeOffset = 0x34;
+				e_phentsizeOffset = 0x36;
+				e_phnumOffset = 0x38;
+				break;
+			default:
+				CCorePlugin.log(IStatus.WARNING, "Unknown ELF header class in file: " + path.toOSString()); //$NON-NLS-1$
+				return false;
+			}
+			if (e_phnumOffset + 2 < hints.length) {
+				boolean isle = (hints[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB);
+				short e_phentsize = makeShort(hints, e_phentsizeOffset, isle);
+				short e_phnum = makeShort(hints, e_phnumOffset, isle);
+				short e_ehsize = makeShort(hints, e_ehsizeOffset, isle);
+				int lastProgramHeaderOffset = e_ehsize + (e_phnum - 1) * e_phentsize;
+				for (int i = e_ehsize; i < Math.min(lastProgramHeaderOffset, hints.length) + 4; i += e_phentsize) {
+					if (makeInt(hints, i, isle) == PHdr.PT_INTERP) {
+						return true;
+					}
+				}
+				/* See if we checked every program header type */
+				if (lastProgramHeaderOffset + 4 < hints.length) {
+					return false;
+				}
+			}
+		}
+
+		try {
+			/* No PHdr.PT_INTERP found in the hints meaning we need to read the file itself */
+			return Arrays.stream(new Elf(path.toOSString()).getPHdrs()).anyMatch(phdr -> phdr.p_type == PHdr.PT_INTERP); 
+		} catch (IOException e) {
+			CCorePlugin.log(e);
+		}
+		return false;
+	}
 }