Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java')
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java82
1 files changed, 68 insertions, 14 deletions
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 108ed1b40d6..65f1e2d2a13 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.core.IBinaryParser;
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 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser {
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 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser {
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 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser {
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;
+ }
}

Back to the top