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
|
2004-02-16 Alain Magloire
|
||||||
|
|
||||||
Added new method getElementAtOffset(), with implementation
|
Added new method getElementAtOffset(), with implementation
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue