1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

fixed bug # 52095

This commit is contained in:
David Inglis 2004-02-17 22:06:12 +00:00
parent af45b6d210
commit 50f8f8a971
3 changed files with 120 additions and 11 deletions

View file

@ -1,3 +1,9 @@
2004-02-17 David Inglis
Fix PR 52095
* utils/org/eclipse/cdt/utils/elf/Elf.java
* utils/org/eclipse/cdt/utils/ElfParser.java
2004-02-16 Alain Magloire 2004-02-16 Alain Magloire
Added new method getElementAtOffset(), with implementation Added new method getElementAtOffset(), with implementation

View file

@ -140,6 +140,54 @@ public class Elf {
e_shnum = efile.readShortE(); e_shnum = efile.readShortE();
e_shstrndx = 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 { public class Section {
@ -591,6 +639,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 { public Elf (String file, long offset) throws IOException {
commonSetup( file, offset, true ); commonSetup( file, offset, true );
} }
@ -656,7 +708,6 @@ public class Elf {
} }
} }
public Attribute getAttributes() throws IOException { public Attribute getAttributes() throws IOException {
Attribute attrib = new Attribute(); Attribute attrib = new Attribute();
@ -753,6 +804,7 @@ public class Elf {
// getSections // getSections
// find .debug using toString // find .debug using toString
Section [] sec = getSections(); Section [] sec = getSections();
if(sec != null) {
for (int i = 0; i < sec.length; i++) { for (int i = 0; i < sec.length; i++) {
String s = sec[i].toString(); String s = sec[i].toString();
if (s.equals(".debug_info")) { if (s.equals(".debug_info")) {
@ -763,10 +815,10 @@ public class Elf {
break; break;
} }
} }
}
return attrib; return attrib;
} }
public static Attribute getAttributes(String file) throws IOException { public static Attribute getAttributes(String file) throws IOException {
Elf elf = new Elf(file); Elf elf = new Elf(file);
Attribute attrib = elf.getAttributes(); Attribute attrib = elf.getAttributes();
@ -774,6 +826,17 @@ public class Elf {
return attrib; 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) { public static boolean isElfHeader(byte[] e_ident) {
if (e_ident.length < 4 || e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' || 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') e_ident[ELFhdr.EI_MAG2] != 'L' || e_ident[ELFhdr.EI_MAG3] != 'F')

View file

@ -22,10 +22,10 @@ import org.eclipse.core.runtime.IPath;
/** /**
*/ */
public class ElfParser extends AbstractCExtension implements IBinaryParser { public class ElfParser extends AbstractCExtension implements IBinaryParser {
byte [] fCachedByteArray;
IPath fCachedPathEntry;
boolean fCachedIsAR;
/**
* @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IPath)
*/
public IBinaryFile getBinary(IPath path) throws IOException { public IBinaryFile getBinary(IPath path) throws IOException {
if (path == null) { if (path == null) {
throw new IOException("path is null"); throw new IOException("path is null");
@ -33,7 +33,30 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser {
BinaryFile binary = null; BinaryFile binary = null;
try { 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) { if (attribute != null) {
switch (attribute.getType()) { switch (attribute.getType()) {
case Attribute.ELF_TYPE_EXE : case Attribute.ELF_TYPE_EXE :
@ -72,7 +95,24 @@ public class ElfParser extends AbstractCExtension implements IBinaryParser {
* @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath) * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath)
*/ */
public boolean isBinary(byte[] array, IPath path) { 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;
} }
} }