Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Inglis2004-02-17 13:42:02 -0500
committerDavid Inglis2004-02-17 13:42:02 -0500
commitff6ecf9502592402fd1e17eaf1f7931920e21653 (patch)
tree4a43bba2f0f8ad8f057a7d2b12eea4aa18a2e14a
parentcd378febc88e7315ddb2ccfc25b77f12ff3b3cee (diff)
downloadorg.eclipse.cdt-ff6ecf9502592402fd1e17eaf1f7931920e21653.tar.gz
org.eclipse.cdt-ff6ecf9502592402fd1e17eaf1f7931920e21653.tar.xz
org.eclipse.cdt-ff6ecf9502592402fd1e17eaf1f7931920e21653.zip
fix for PR52095
-rw-r--r--core/org.eclipse.cdt.core/ChangeLog8
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java83
-rw-r--r--core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java47
3 files changed, 126 insertions, 12 deletions
diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog
index d01b19ec91..f0ee58b475 100644
--- a/core/org.eclipse.cdt.core/ChangeLog
+++ b/core/org.eclipse.cdt.core/ChangeLog
@@ -1,3 +1,11 @@
+2004-02-17 David Inglis
+
+ PR 52095
+ Patch from thomasf to cache data block from IBinarParser.isBinary.
+
+ * utils/org/eclipse/cdt/utils/elf/Elf.java
+ * utils/org/eclipse/cdt/uilts/elf/parser/ElfParser.java
+
2004-02-05 Alain Magloire
PR 50810
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 dc8c2332f4..9801cd7744 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
@@ -140,6 +140,54 @@ public class Elf {
e_shnum = efile.readShortE();
e_shstrndx = efile.readShortE();
}
+
+ protected ELFhdr(byte [] bytes) throws IOException {
+ if(bytes.length <= e_ident.length) {
+ throw new IOException("Not ELF format");
+ }
+ System.arraycopy(bytes, 0, e_ident, 0, e_ident.length);
+ if ( e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' ||
+ e_ident[ELFhdr.EI_MAG2] != 'L' || e_ident[ELFhdr.EI_MAG3] != 'F' )
+ throw new IOException("Not ELF format");
+ boolean isle = (e_ident[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB);
+ int offset = e_ident.length;
+ e_type = makeShort(bytes, offset, isle); offset += 2;
+ e_machine = makeShort(bytes, offset, isle); offset += 2;
+ e_version = makeInt(bytes, offset, isle); offset += 4;
+ e_entry = makeInt(bytes, offset, isle); offset += 4;
+ e_phoff = makeInt(bytes, offset, isle); offset += 4;
+ e_shoff = makeInt(bytes, offset, isle); offset += 4;
+ e_flags = makeInt(bytes, offset, isle); offset += 4;
+ e_ehsize = makeShort(bytes, offset, isle); offset += 2;
+ e_phentsize = makeShort(bytes, offset, isle); offset += 2;
+ e_phnum = makeShort(bytes, offset, isle); offset += 2;
+ e_shentsize = makeShort(bytes, offset, isle); offset += 2;
+ e_shnum = makeShort(bytes, offset, isle); offset += 2;
+ e_shstrndx = makeShort(bytes, offset, isle); offset += 2;
+ }
+
+ private final short makeShort(byte [] val, int offset, boolean isle) throws IOException {
+ if (val.length < offset + 2)
+ throw new IOException();
+ if ( isle ) {
+ return (short)((val[offset + 1] << 8) + val[offset + 0]);
+ } else {
+ return (short)((val[offset + 0] << 8) + val[offset + 1]);
+ }
+ }
+
+ private final long makeInt(byte [] val, int offset, boolean isle) throws IOException
+ {
+ if (val.length < offset + 4)
+ throw new IOException();
+ if ( isle ) {
+ return ((val[offset + 3] << 24) + (val[offset + 2] << 16) + (val[offset + 1] << 8) + val[offset + 0]);
+ } else {
+ return ((val[offset + 0] << 24) + (val[offset + 1] << 16) + (val[offset + 2] << 8) + val[offset + 3]);
+ }
+ }
+
+
}
public class Section {
@@ -590,6 +638,10 @@ public class Elf {
}
}
}
+
+ //A hollow entry, to be used with caution in controlled situations
+ protected Elf () {
+ }
public Elf (String file, long offset) throws IOException {
commonSetup( file, offset, true );
@@ -647,11 +699,10 @@ public class Elf {
}
}
-
public Attribute getAttributes() throws IOException {
- Attribute attrib = new Attribute();
-
- switch( ehdr.e_type ) {
+ Attribute attrib = new Attribute();
+
+ switch( ehdr.e_type ) {
case Elf.ELFhdr.ET_CORE:
attrib.type = Attribute.ELF_TYPE_CORE;
break;
@@ -744,23 +795,35 @@ public class Elf {
// getSections
// find .debug using toString
Section [] sec = getSections();
- for (int i = 0; i < sec.length; i++) {
- String s = sec[i].toString();
- attrib.bDebug = (s.startsWith(".debug") || s. equals(".stab"));
- if (attrib.bDebug) {
- break;
+ if(sec != null) {
+ for (int i = 0; i < sec.length; i++) {
+ String s = sec[i].toString();
+ attrib.bDebug = (s.startsWith(".debug") || s. equals(".stab"));
+ if (attrib.bDebug) {
+ break;
+ }
}
}
return attrib;
}
-
public static Attribute getAttributes(String file) throws IOException {
Elf elf = new Elf(file);
Attribute attrib = elf.getAttributes();
elf.dispose();
return attrib;
}
+
+ public static Attribute getAttributes(byte [] array) throws IOException {
+
+ Elf emptyElf = new Elf();
+ emptyElf.ehdr = emptyElf.new ELFhdr(array);
+ emptyElf.sections = new Elf.Section[0];
+ Attribute attrib = emptyElf.getAttributes();
+ emptyElf.dispose();
+
+ return attrib;
+ }
public static boolean isElfHeader(byte[] e_ident) {
if (e_ident.length < 4 || e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' ||
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 b3c4679ab6..8a25bb812c 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
@@ -22,6 +22,9 @@ import org.eclipse.core.runtime.IPath;
/**
*/
public class ElfParser extends AbstractCExtension implements IBinaryParser {
+ byte [] fCachedByteArray;
+ IPath fCachedPathEntry;
+ boolean fCachedIsAR;
/**
* @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IPath)
@@ -33,7 +36,30 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser {
BinaryFile binary = null;
try {
- Elf.Attribute attribute = Elf.getAttributes(path.toOSString());
+ Elf.Attribute attribute = null;
+
+ //Try our luck with the cached entry first, then clear it
+ if(fCachedPathEntry != null && fCachedPathEntry.equals(path)) {
+ try {
+ //Don't bother with ELF stuff if this is an archive
+ if(fCachedIsAR) {
+ return new BinaryArchive(path);
+ }
+ //Well, if it wasn't an archive, go for broke
+ attribute = Elf.getAttributes(fCachedByteArray);
+ } catch(Exception ex) {
+ attribute = null;
+ } finally {
+ fCachedPathEntry = null;
+ fCachedByteArray = null;
+ }
+ }
+
+ //Take a second run at it if the cache failed.
+ if(attribute == null) {
+ attribute = Elf.getAttributes(path.toOSString());
+ }
+
if (attribute != null) {
switch (attribute.getType()) {
case Attribute.ELF_TYPE_EXE :
@@ -72,7 +98,24 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser {
* @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath)
*/
public boolean isBinary(byte[] array, IPath path) {
- return Elf.isElfHeader(array) || AR.isARHeader(array);
+ boolean isBinaryReturnValue = false;
+
+ if(Elf.isElfHeader(array)) {
+ isBinaryReturnValue = true;
+ fCachedIsAR = false;
+ } else if(AR.isARHeader(array)) {
+ isBinaryReturnValue = true;
+ fCachedIsAR = true;
+ }
+
+ //If it is a binary, then cache the array in anticipation that we will be asked to do something with it
+ if(isBinaryReturnValue && array.length > 0) {
+ fCachedPathEntry = path;
+ fCachedByteArray = new byte[array.length];
+ System.arraycopy(array, 0, fCachedByteArray, 0, array.length);
+ }
+
+ return isBinaryReturnValue;
}
}

Back to the top