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:
parent
af45b6d210
commit
50f8f8a971
3 changed files with 120 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -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' ||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue