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
Added new method getElementAtOffset(), with implementation

View file

@ -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 );
@ -656,11 +708,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;
@ -753,6 +804,7 @@ public class Elf {
// getSections
// find .debug using toString
Section [] sec = getSections();
if(sec != null) {
for (int i = 0; i < sec.length; i++) {
String s = sec[i].toString();
if (s.equals(".debug_info")) {
@ -763,16 +815,27 @@ public class Elf {
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' ||

View file

@ -22,10 +22,10 @@ import org.eclipse.core.runtime.IPath;
/**
*/
public class ElfParser extends AbstractCExtension implements IBinaryParser {
/**
* @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IPath)
*/
byte [] fCachedByteArray;
IPath fCachedPathEntry;
boolean fCachedIsAR;
public IBinaryFile getBinary(IPath path) throws IOException {
if (path == null) {
throw new IOException("path is null");
@ -33,7 +33,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 +95,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;
}
}