From 9e051b52c2a88d5d7240aefaae2ee8e5109c72c6 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Fri, 17 Sep 2004 18:05:03 +0000 Subject: [PATCH] Jumbo patch from Artyom Kuanbekov PR 69908 Support for 64 bits --- core/org.eclipse.cdt.core/ChangeLog | 6 + .../org/eclipse/cdt/core/model/IBinary.java | 4 + .../cdt/core/model/IBinaryElement.java | 4 +- .../cdt/internal/core/model/Binary.java | 12 + .../internal/core/model/BinaryElement.java | 7 +- .../internal/core/model/BinaryFunction.java | 3 +- .../cdt/internal/core/model/BinaryModule.java | 5 +- .../internal/core/model/BinaryVariable.java | 3 +- .../src/org/eclipse/cdt/core/IAddress.java | 83 +++++ .../org/eclipse/cdt/core/IAddressFactory.java | 51 +++ .../org/eclipse/cdt/core/IBinaryParser.java | 5 +- .../org/eclipse/cdt/utils/Addr2line.java | 18 +- .../utils/org/eclipse/cdt/utils/Addr32.java | 143 +++++++++ .../org/eclipse/cdt/utils/Addr32Factory.java | 44 +++ .../utils/org/eclipse/cdt/utils/Addr64.java | 130 ++++++++ .../org/eclipse/cdt/utils/Addr64Factory.java | 42 +++ .../cdt/utils/BinaryObjectAdapter.java | 19 +- .../utils/org/eclipse/cdt/utils/Symbol.java | 25 +- .../utils/org/eclipse/cdt/utils/coff/PE.java | 10 + .../cdt/utils/coff/parser/ARMember.java | 3 +- .../coff/parser/CygwinPEBinaryObject.java | 7 +- .../cdt/utils/coff/parser/CygwinSymbol.java | 8 +- .../cdt/utils/coff/parser/PEBinaryObject.java | 4 +- .../cdt/utils/elf/ERandomAccessFile.java | 34 ++ .../utils/org/eclipse/cdt/utils/elf/Elf.java | 298 ++++++++++++++++-- .../cdt/utils/elf/parser/ElfBinaryObject.java | 1 + .../utils/elf/parser/GNUElfBinaryObject.java | 6 +- .../cdt/utils/elf/parser/GNUSymbol.java | 8 +- .../cdt/utils/macho/parser/ARMember.java | 3 +- .../utils/macho/parser/MachOBinaryObject.java | 3 +- .../cdt/utils/som/parser/ARMember.java | 6 +- .../cdt/utils/som/parser/SOMBinaryObject.java | 8 +- .../cdt/utils/som/parser/SomSymbol.java | 8 +- .../cdt/utils/xcoff/parser/ARMember.java | 3 +- .../utils/xcoff/parser/XCOFFBinaryObject.java | 7 +- .../cdt/utils/xcoff/parser/XCoffSymbol.java | 8 +- 36 files changed, 931 insertions(+), 98 deletions(-) create mode 100644 core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IAddress.java create mode 100644 core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IAddressFactory.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32Factory.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64Factory.java diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index c007f85c3ff..c1267133c20 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,9 @@ +2004-09-15 Alain Magloire + + Jumbo patch from Artyom Kuanbekov + PR 69908 + Support for 64 bits + 2004-09-14 Alain Magloire Try to find the function in the header. * model/org/eclipse/cdt/internal/core/model/BinaryElement.java diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IBinary.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IBinary.java index 2d0532d486e..62713275b76 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IBinary.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IBinary.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.cdt.core.model; +import org.eclipse.cdt.core.IAddressFactory; + /** * Represents a Binary file, for example an ELF excutable. @@ -43,4 +45,6 @@ public interface IBinary extends ICElement, IParent, IOpenable { public boolean isLittleEndian(); + public IAddressFactory getAddressFactory(); + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IBinaryElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IBinaryElement.java index 28e1e4201b4..8f987b767b9 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IBinaryElement.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IBinaryElement.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.cdt.core.model; +import org.eclipse.cdt.core.IAddress; + /** */ @@ -22,7 +24,7 @@ public interface IBinaryElement extends ICElement { * @exception CModelException if this element does not have address * information. */ - long getAddress() throws CModelException; + IAddress getAddress() throws CModelException; /** * Returns the binary object the element belongs to. diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java index 74a783dafac..3e5a9a9a165 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java @@ -17,6 +17,7 @@ import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; +import org.eclipse.cdt.core.IAddressFactory; import org.eclipse.cdt.core.IBinaryParser.IBinaryExecutable; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; @@ -43,6 +44,7 @@ public class Binary extends Openable implements IBinary { private long longBSS; private String endian; private String soname; + private IAddressFactory addressFactory; private long fLastModification; @@ -172,6 +174,15 @@ public class Binary extends Openable implements IBinary { return binaryObject; } + public IAddressFactory getAddressFactory() { + if (isObject() || isExecutable() || isSharedLib() || isCore()) { + if (addressFactory == null || hasChanged()) { + addressFactory = getBinaryObject().getAddressFactory(); + } + } + return addressFactory; + } + protected int getType() { IBinaryObject obj = getBinaryObject(); if (obj != null && (fBinType == 0 || hasChanged())) { @@ -193,6 +204,7 @@ public class Binary extends Openable implements IBinary { longData = -1; longText = -1; soname = null; + addressFactory = null; } return changed; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryElement.java index 15ef7a0b0a2..507dfae57e5 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryElement.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryElement.java @@ -7,6 +7,7 @@ package org.eclipse.cdt.internal.core.model; import java.io.IOException; import java.util.Map; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.IBinaryElement; @@ -27,9 +28,9 @@ import org.eclipse.core.runtime.Path; */ public class BinaryElement extends CElement implements IBinaryElement, ISourceManipulation, ISourceReference { - long addr; + IAddress addr; - public BinaryElement(ICElement parent, String name, int type, long a) { + public BinaryElement(ICElement parent, String name, int type, IAddress a) { super(parent, name, type); addr = a; } @@ -153,7 +154,7 @@ public class BinaryElement extends CElement implements IBinaryElement, ISourceMa /* (non-Javadoc) * @see org.eclipse.cdt.core.model.IBinaryElement#getAddress() */ - public long getAddress() throws CModelException { + public IAddress getAddress() throws CModelException { return addr; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryFunction.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryFunction.java index da8d61c4df9..89da03bc99b 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryFunction.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryFunction.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.internal.core.model; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.model.IBinaryFunction; import org.eclipse.cdt.core.model.ICElement; @@ -18,7 +19,7 @@ import org.eclipse.cdt.core.model.ICElement; */ public class BinaryFunction extends BinaryElement implements IBinaryFunction { - public BinaryFunction(ICElement parent, String name, long a) { + public BinaryFunction(ICElement parent, String name, IAddress a) { super(parent, name, ICElement.C_FUNCTION, a); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryModule.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryModule.java index d3fea333ec3..bb59db72f11 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryModule.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryModule.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.model; import java.util.Map; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.IBinaryElement; @@ -47,8 +48,8 @@ public class BinaryModule extends Parent implements IBinaryModule { /* (non-Javadoc) * @see org.eclipse.cdt.core.model.IBinaryElement#getAddress() */ - public long getAddress() throws CModelException { - return 0; + public IAddress getAddress() throws CModelException { + return null; } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryVariable.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryVariable.java index 070fc2a2b92..e41143cc284 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryVariable.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryVariable.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.model; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IVariable; @@ -18,7 +19,7 @@ import org.eclipse.cdt.core.model.IVariable; */ public class BinaryVariable extends BinaryElement implements IVariable { - public BinaryVariable(ICElement parent, String name, long a) { + public BinaryVariable(ICElement parent, String name, IAddress a) { super(parent, name, ICElement.C_VARIABLE, a); } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IAddress.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IAddress.java new file mode 100644 index 00000000000..cbde33cd4f6 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IAddress.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2004 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core; + +import java.math.BigInteger; + +/* + * Represents C/C++ address in CDT. All implementors of this inteface should be + * immutable, i.e. all methods should not modify objects, they should return + * new object. + * + * Please see Addr32 and Addr64 classes to see how this interface should + * be extended + */ +public interface IAddress +{ + /* + * Return adds offset to address and returns new address object + * which is the result + */ + IAddress add(BigInteger offset); + /* + * Returns maximal offset possible for address. The offset + * should be Identicall for all addresses of given class. + */ + BigInteger getMaxOffset(); + /* + * Returns distance between two addresses. Distance may be positive or negative + */ + BigInteger distance(IAddress other); + /* + * Compares two addresses. + * + * Returns: + * -1 if this < addr + * 0 if this == addr + * 1 if this > addr + */ + int compareTo(IAddress addr); + /* + * Returns true if addresses are equal + */ + boolean equals(IAddress addr); + /* + * Return true if address is zero, i.e. minimal possible + */ + boolean isZero(); + /* + * Return true if address is maximal, i.e. maximal possible + */ + boolean isMax(); + + /* + * Converts address to string as an unsigned number with given radix + */ + String toString(int radix); + /* + * Identical to toString(10) + */ + String toString(); + /* + * Converts address to the hex representation with '0x' prefix and + * with all leading zeros. The length of returned string should be + * the same for all addresses of given class. I.e. 10 for 32-bit + * addresses and 18 for 64-bit addresses + */ + String toHexAddressString(); + + /* + * Returns amount of symbols in hex representation. Is identical to + * toHexAddressString().length(). It is present for perfomance purpose. + */ + int getCharsNum(); + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IAddressFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IAddressFactory.java new file mode 100644 index 00000000000..a0e9edeefd3 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IAddressFactory.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2004 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core; + + +/* + * This inteface serves as an address factory. If you need to + * implement your own addresses, you should extend this. + * + * Please see Addr32Factory and Addr64Factory to see how it can be implemented. + */ +public interface IAddressFactory +{ + /* + * Returns zero address, i.e. minimal possible address + */ + IAddress getZero(); + /* + * Returns maximal address. + */ + IAddress getMax(); + /* + * Creates address from string representation. + * + * 1. This method should be able to create address from hex + * address string (string produced with + * IAddress.toHexAddressString() method). + * 2. Method should be case insensetive + * 3. Method should be able to create address from decimal address + * representation + * + * Please see Addr32Factory.createAddress() for reference implementation. + */ + IAddress createAddress(String addr); + /* + * Creates address from string with given radix. + * + * Given string should not contain any prefixes or sign numbers. + * + * Method should be case insensetive + */ + IAddress createAddress(String addr, int radix); +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IBinaryParser.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IBinaryParser.java index cce0534e35d..95641be9b8d 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IBinaryParser.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IBinaryParser.java @@ -121,7 +121,7 @@ public interface IBinaryParser extends IAdaptable { * @param addr * @return ISymbol */ - ISymbol getSymbol(long addr); + ISymbol getSymbol(IAddress addr); /** * The name of the object @@ -129,6 +129,7 @@ public interface IBinaryParser extends IAdaptable { */ String getName(); + IAddressFactory getAddressFactory(); } /** @@ -176,7 +177,7 @@ public interface IBinaryParser extends IAdaptable { * Address of the symbol * @return */ - long getAddress(); + IAddress getAddress(); /** * Size of the symbol. diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr2line.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr2line.java index 7796268ce22..afbecdbe73b 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr2line.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr2line.java @@ -15,7 +15,9 @@ import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.math.BigInteger; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.utils.spawner.ProcessFactory; public class Addr2line { @@ -61,13 +63,13 @@ public class Addr2line { } } - public String getLine(long address) throws IOException { - getOutput(Integer.toHexString((int)address)); + public String getLine(IAddress address) throws IOException { + getOutput(address.toString(16)); return lastline; } - public String getFunction(long address) throws IOException { - getOutput(Integer.toHexString((int)address)); + public String getFunction(IAddress address) throws IOException { + getOutput(address.toString(16)); return lastsymbol; } @@ -78,7 +80,7 @@ public class Addr2line { * main * hello.c:39 */ - public String getFileName(long address) throws IOException { + public String getFileName(IAddress address) throws IOException { String filename = null; String line = getLine(address); int index1, index2; @@ -103,12 +105,14 @@ public class Addr2line { * main * hello.c:39 */ - public int getLineNumber(long address) throws IOException { + public int getLineNumber(IAddress address) throws IOException { // We try to get the nearest match // since the symbol may not exactly align with debug info. // In C line number 0 is invalid, line starts at 1 for file, we use // this for validation. - for (int i = 0; i <= 20; i += 4, address += i) { + + //IPF_TODO: check + for (int i = 0; i <= 20; i += 4, address = address.add(BigInteger.valueOf(i))) { String line = getLine(address); if (line != null) { int colon = line.lastIndexOf(':'); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32.java new file mode 100644 index 00000000000..713fc84bb60 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2004 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.utils; + +import java.math.BigInteger; + +import org.eclipse.cdt.core.IAddress; + +/* + */ +final public class Addr32 implements IAddress +{ + public static final Addr32 ZERO=new Addr32(0); + public static final Addr32 MAX=new Addr32(0xffffffffL); + + public static final BigInteger MAX_OFFSET = BigInteger.valueOf(0xffffffffL); + + public static final int BYTES_NUM = 4; + public static final int DIGITS_NUM = BYTES_NUM * 2; + public static final int CHARS_NUM = DIGITS_NUM + 2; + + private long address; + + /* + * addrBytes should be 4 bytes length + */ + public Addr32(byte [] addrBytes) + { + /*We should mask out sign bits to have correct value*/ + this.address = ( ( ((long)addrBytes[0]) << 24 ) & 0xFF000000L) + + ( ( ((long)addrBytes[1]) << 16 ) & 0x00FF0000L) + + ( ( ((long)addrBytes[2]) << 8 ) & 0x0000FF00L) + + ( ((long)addrBytes[3]) & 0x000000FFL); + } + + public Addr32(long rawaddress) + { + this.address=rawaddress; + } + + public Addr32(String addr) + { + addr = addr.toLowerCase(); + if ( addr.startsWith( "0x" ) ) + { + this.address = Long.parseLong(addr.substring(2), 16); + } + else + { + this.address = Long.parseLong(addr, 10); + } + } + + public Addr32(String addr, int radix) + { + this.address=Long.parseLong(addr, radix); + } + + final public IAddress add(BigInteger offset) + { + return new Addr32(this.address + offset.longValue()); + } + + final public BigInteger getMaxOffset() + { + return MAX_OFFSET; + } + + final public BigInteger distance(IAddress other) + { + return BigInteger.valueOf(address - ((Addr32)other).address); + } + + final public int compareTo(IAddress addr) + { + if (address > ((Addr32)addr).address) + { + return 1; + } + if (address < ((Addr32)addr).address) + { + return -1; + } + return 0; + } + + final public boolean isMax() + { + return address == MAX.address; + } + + final public boolean isZero() + { + return address == ZERO.address; + } + + final public String toString() + { + return toString(10); + } + + final public String toString(int radix) + { + return Long.toString(address, radix); + } + + final public boolean equals(IAddress x) + { + if (x == this) + return true; + if (!(x instanceof Addr32)) + return false; + return this.address == ((Addr32)x).address; + } + + final public String toHexAddressString( ) + { + String addressString = Long.toString(address,16); + StringBuffer sb = new StringBuffer( CHARS_NUM ); + int count = DIGITS_NUM - addressString.length(); + sb.append( "0x" ); + for ( int i = 0; i < count ; ++i ) + { + sb.append( '0' ); + } + sb.append( addressString ); + return sb.toString(); + } + + final public int getCharsNum() + { + return CHARS_NUM; + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32Factory.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32Factory.java new file mode 100644 index 00000000000..029be6546df --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr32Factory.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2004 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.utils; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.IAddressFactory; + + +/* + */ +final public class Addr32Factory implements IAddressFactory +{ + + final public IAddress getZero() + { + return Addr32.ZERO; + } + + final public IAddress getMax() + { + return Addr32.MAX; + } + + final public IAddress createAddress(String addr) + { + IAddress address=new Addr32(addr); + return address; + } + + final public IAddress createAddress(String addr, int radix) + { + IAddress address=new Addr32(addr, radix); + return address; + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64.java new file mode 100644 index 00000000000..2d78ab3898b --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2004 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.utils; + +import java.math.BigInteger; + +import org.eclipse.cdt.core.IAddress; + +/* + */ +final public class Addr64 implements IAddress +{ + public static final Addr64 ZERO=new Addr64("0"); + public static final Addr64 MAX=new Addr64("ffffffffffffffff",16); + + public static final BigInteger MAX_OFFSET = new BigInteger("ffffffffffffffff",16); + + public static final int BYTES_NUM = 8; + public static final int DIGITS_NUM = BYTES_NUM * 2; + public static final int CHARS_NUM = DIGITS_NUM + 2; + + private BigInteger address; + + public Addr64(byte [] addrBytes) + { + if( addrBytes.length != 8) + throw(new NumberFormatException("Invalid address array")); + this.address = new BigInteger(1, addrBytes); + } + + public Addr64(BigInteger rawaddress) + { + this.address=rawaddress; + } + + public Addr64(String addr) + { + addr = addr.toLowerCase(); + if ( addr.startsWith( "0x" ) ) + { + this.address = new BigInteger(addr.substring(2), 16); + } + else + { + this.address = new BigInteger(addr, 10); + } + } + + public Addr64(String addr, int radix) + { + this.address=new BigInteger(addr, radix); + } + + final public IAddress add(BigInteger offset) + { + return new Addr64(this.address.add(offset)); + } + + final public BigInteger getMaxOffset() + { + return MAX_OFFSET; + } + + final public BigInteger distance(IAddress other) + { + return address.add(((Addr64)other).address.negate()); + } + + final public boolean isMax() + { + return address.equals(MAX); + } + + final public boolean isZero() + { + return address.equals(ZERO); + } + + final public int compareTo(IAddress addr) + { + return this.address.compareTo(((Addr64)addr).address); + } + + final public boolean equals(IAddress x) + { + if (x == this) + return true; + if (!(x instanceof Addr64)) + return false; + return this.address.equals(((Addr64)x).address); + } + + final public String toString() + { + return toString(10); + } + + final public String toString(int radix) + { + return address.toString(radix); + } + + final public String toHexAddressString( ) + { + String addressString = address.toString(16); + StringBuffer sb = new StringBuffer( CHARS_NUM ); + int count = DIGITS_NUM - addressString.length(); + sb.append( "0x" ); + for ( int i = 0; i < count; ++i ) + { + sb.append( '0' ); + } + sb.append( addressString ); + return sb.toString(); + } + + final public int getCharsNum() + { + return CHARS_NUM; + } +} + diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64Factory.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64Factory.java new file mode 100644 index 00000000000..e22c11e98cd --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Addr64Factory.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2004 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.utils; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.IAddressFactory; + + +/* + */ +final public class Addr64Factory implements IAddressFactory{ + + final public IAddress getZero() + { + return Addr64.ZERO; + } + + final public IAddress getMax() + { + return Addr64.MAX; + } + + final public IAddress createAddress(String addr) + { + IAddress address=new Addr64(addr); + return address; + } + + final public IAddress createAddress(String addr, int radix) + { + IAddress address=new Addr64(addr, radix); + return address; + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/BinaryObjectAdapter.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/BinaryObjectAdapter.java index 861f9872a6d..119f105b025 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/BinaryObjectAdapter.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/BinaryObjectAdapter.java @@ -10,8 +10,11 @@ *******************************************************************************/ package org.eclipse.cdt.utils; +import java.math.BigInteger; import java.util.Arrays; +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.IAddressFactory; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser.IBinaryExecutable; import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; @@ -35,6 +38,7 @@ public abstract class BinaryObjectAdapter extends BinaryFile implements IBinaryO public String soname; public String[] needed; public String cpu; + public IAddressFactory addressFactory; public BinaryObjectInfo() { cpu = soname = ""; //$NON-NLS-1$ @@ -49,9 +53,9 @@ public abstract class BinaryObjectAdapter extends BinaryFile implements IBinaryO /* (non-Javadoc) * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbol(long) */ - public ISymbol getSymbol(long addr) { + public ISymbol getSymbol(IAddress addr) { ISymbol[] syms = getSymbols(); - int insertion = Arrays.binarySearch(syms, new Long(addr)); + int insertion = Arrays.binarySearch(syms, addr); if (insertion >= 0) { return syms[insertion]; } @@ -60,7 +64,7 @@ public abstract class BinaryObjectAdapter extends BinaryFile implements IBinaryO } insertion = -insertion - 1; ISymbol symbol = syms[insertion - 1]; - if (addr < (symbol.getAddress() + symbol.getSize())) { + if (addr.compareTo(symbol.getAddress().add(BigInteger.valueOf(symbol.getSize()))) < 0) { return syms[insertion - 1]; } return null; @@ -153,7 +157,14 @@ public abstract class BinaryObjectAdapter extends BinaryFile implements IBinaryO } return ""; //$NON-NLS-1$ } - + public IAddressFactory getAddressFactory() + { + BinaryObjectInfo info = getBinaryObjectInfo(); + if (info != null) { + return info.addressFactory; + } + return null; //$NON-NLS-1$ + } /** * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName() */ diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Symbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Symbol.java index 1fe19782458..c10b6710405 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Symbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/Symbol.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.utils; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; import org.eclipse.cdt.core.IBinaryParser.ISymbol; import org.eclipse.core.runtime.IPath; @@ -19,14 +20,14 @@ public class Symbol implements ISymbol, Comparable { protected final BinaryObjectAdapter binary; private final String name; - private final long addr; + private final IAddress addr; private final int type; private final long size; private final int startLine; private final int endLine; private final IPath sourceFile; - public Symbol(BinaryObjectAdapter binary, String name, int type, long addr, long size, IPath sourceFile, int startLine, int endLine) { + public Symbol(BinaryObjectAdapter binary, String name, int type, IAddress addr, long size, IPath sourceFile, int startLine, int endLine) { this.binary = binary; this.name = name; this.type = type; @@ -37,7 +38,7 @@ public class Symbol implements ISymbol, Comparable { this.sourceFile = sourceFile; } - public Symbol(BinaryObjectAdapter binary, String name, int type, long addr, long size) { + public Symbol(BinaryObjectAdapter binary, String name, int type, IAddress addr, long size) { this.binary = binary; this.name = name; this.type = type; @@ -81,7 +82,7 @@ public class Symbol implements ISymbol, Comparable { * * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getAdress() */ - public long getAddress() { + public IAddress getAddress() { return addr; } @@ -122,17 +123,13 @@ public class Symbol implements ISymbol, Comparable { } public int compareTo(Object obj) { - long thisVal = 0; - long anotherVal = 0; + IAddress thisVal = this.addr; + IAddress anotherVal = null; if (obj instanceof Symbol) { - Symbol sym = (Symbol) obj; - thisVal = this.addr; - anotherVal = sym.addr; - } else if (obj instanceof Long) { - Long val = (Long) obj; - anotherVal = val.longValue(); - thisVal = this.addr; + anotherVal = ((Symbol) obj).addr; + } else if (obj instanceof IAddress) { + anotherVal = (IAddress) obj; } - return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1)); + return thisVal.compareTo(anotherVal); } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java index 766e43e8cb5..0b0f434ba14 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java @@ -15,6 +15,8 @@ import java.io.IOException; import java.io.RandomAccessFile; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IAddressFactory; +import org.eclipse.cdt.utils.Addr32Factory; import org.eclipse.cdt.utils.coff.Coff.FileHeader; import org.eclipse.cdt.utils.coff.Coff.OptionalHeader; import org.eclipse.cdt.utils.coff.Coff.SectionHeader; @@ -84,6 +86,7 @@ public class PE { int word; boolean bDebug; boolean isle; + IAddressFactory addrFactory; public String getCPU() { return cpu; @@ -104,6 +107,11 @@ public class PE { public int getWord() { return word; } + + public IAddressFactory getAddressFactory(){ + return addrFactory; + } + } /** @@ -462,6 +470,8 @@ public class PE { if ((filhdr.f_flags & PEConstants.IMAGE_FILE_32BIT_MACHINE) != 0) { attrib.word = 32; } + + attrib.addrFactory = new Addr32Factory(); return attrib; } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java index 6d5db02cb0a..7a90ca61927 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java @@ -18,6 +18,7 @@ import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.Symbol; import org.eclipse.cdt.utils.coff.Coff; import org.eclipse.cdt.utils.coff.PE; @@ -77,7 +78,7 @@ public class ARMember extends PEBinaryObject { continue; } int type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE; - list.add(new Symbol(this, name, type, peSyms[i].n_value, 1)); + list.add(new Symbol(this, name, type, new Addr32(peSyms[i].n_value), 1)); } } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java index ddd617ef5b2..beb010fe81d 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java @@ -11,10 +11,13 @@ package org.eclipse.cdt.utils.coff.parser; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.math.BigInteger; import java.util.List; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IBinaryParser.ISymbol; import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.CPPFilt; import org.eclipse.cdt.utils.CygPath; import org.eclipse.cdt.utils.Objdump; @@ -147,7 +150,7 @@ public class CygwinPEBinaryObject extends PEBinaryObject { continue; } int type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE; - int addr = peSyms[i].n_value; + IAddress addr = new Addr32(peSyms[i].n_value); int size = 4; if (cppfilt != null) { try { @@ -172,7 +175,7 @@ public class CygwinPEBinaryObject extends PEBinaryObject { } IPath file = filename != null ? new Path(filename) : Path.EMPTY; int startLine = addr2line.getLineNumber(addr); - int endLine = addr2line.getLineNumber(addr + size - 1); + int endLine = addr2line.getLineNumber(addr.add(BigInteger.valueOf(size - 1))); list.add(new CygwinSymbol(this, name, type, addr, size, file, startLine, endLine)); } catch (IOException e) { addr2line = null; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol.java index a4ee24f9368..36ded63761d 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/CygwinSymbol.java @@ -7,7 +7,9 @@ package org.eclipse.cdt.utils.coff.parser; import java.io.IOException; +import java.math.BigInteger; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.utils.Addr2line; import org.eclipse.cdt.utils.Symbol; import org.eclipse.core.runtime.IPath; @@ -31,7 +33,7 @@ class CygwinSymbol extends Symbol { * @param startLine * @param endLine */ - public CygwinSymbol(CygwinPEBinaryObject binary, String name, int type, long addr, long size, IPath sourceFile, int startLine, + public CygwinSymbol(CygwinPEBinaryObject binary, String name, int type, IAddress addr, long size, IPath sourceFile, int startLine, int endLine) { super(binary, name, type, addr, size, sourceFile, startLine, endLine); } @@ -43,7 +45,7 @@ class CygwinSymbol extends Symbol { * @param addr * @param size */ - public CygwinSymbol(CygwinPEBinaryObject binary, String name, int type, long addr, long size) { + public CygwinSymbol(CygwinPEBinaryObject binary, String name, int type, IAddress addr, long size) { super(binary, name, type, addr, size); } @@ -55,7 +57,7 @@ class CygwinSymbol extends Symbol { Addr2line addr2line = ((CygwinPEBinaryObject)binary).getAddr2line(true); if (addr2line != null) { try { - return addr2line.getLineNumber(getAddress() + offset); + return addr2line.getLineNumber(getAddress().add(BigInteger.valueOf(offset))); } catch (IOException e) { // ignore } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java index 82d63b11f5e..09686dc9815 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java @@ -18,6 +18,7 @@ import java.util.List; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.BinaryObjectAdapter; import org.eclipse.cdt.utils.Symbol; import org.eclipse.cdt.utils.coff.Coff; @@ -107,6 +108,7 @@ public class PEBinaryObject extends BinaryObjectAdapter { info.isLittleEndian = attribute.isLittleEndian(); info.hasDebug = attribute.hasDebug(); info.cpu = attribute.getCPU(); + info.addressFactory = attribute.getAddressFactory(); } protected void loadSymbols(PE pe) throws IOException { @@ -129,7 +131,7 @@ public class PEBinaryObject extends BinaryObjectAdapter { continue; } int type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE; - list.add(new Symbol(this, name, type, peSyms[i].n_value, 1)); + list.add(new Symbol(this, name, type, new Addr32(peSyms[i].n_value), 1)); } } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ERandomAccessFile.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ERandomAccessFile.java index 1b0b87d6418..41b6efdc20a 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ERandomAccessFile.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ERandomAccessFile.java @@ -59,6 +59,40 @@ public class ERandomAccessFile extends RandomAccessFile { return ((val[0] << 24) + (val[1] << 16) + (val[2] << 8) + val[3]); } + public final long readLongE() throws IOException + { + byte [] bytes = new byte[8]; + long result = 0; + super.readFully(bytes); + int shift = 0; + if ( isle ) + for(int i=7; i >= 0; i-- ) + { + shift = i*8; + result += ( ((long)bytes[i]) << shift ) & ( 0xffL << shift ); + } + else + for(int i=0; i <= 7; i++ ) + { + shift = (7-i)*8; + result += ( ((long)bytes[i]) << shift ) & ( 0xffL << shift ); + } + return result; + } + + public final void readFullyE(byte [] bytes) throws IOException + { + super.readFully(bytes); + byte tmp = 0; + if( isle ) + for(int i=0; i <= bytes.length / 2; i++) + { + tmp = bytes[i]; + bytes[i] = bytes[bytes.length - i -1]; + bytes[bytes.length - i -1] = tmp; + } + } + public void setFileOffset( long offset ) throws IOException { ptr_offset = offset; super.seek( offset ); 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 b594aadb283..6fd3d7a1e83 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 @@ -18,9 +18,20 @@ import java.util.Arrays; import java.util.Comparator; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.core.IAddressFactory; +import org.eclipse.cdt.utils.Addr32; +import org.eclipse.cdt.utils.Addr32Factory; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.cdt.utils.Addr64Factory; // test checkin public class Elf { + public final static int ELF32_ADDR_SIZE = 4; + public final static int ELF32_OFF_SIZE = 4; + public final static int ELF64_ADDR_SIZE = 8; + public final static int ELF64_OFF_SIZE = 8; + protected ERandomAccessFile efile; protected ELFhdr ehdr; @@ -52,7 +63,7 @@ public class Elf { /* e_ident[EI_CLASS] */ public final static int ELFCLASSNONE = 0; - public final static int ELCLASS32 = 1; + public final static int ELFCLASS32 = 1; public final static int ELFCLASS64 = 2; /* e_ident[EI_DATA] */ @@ -117,7 +128,7 @@ public class Elf { public int e_type; /* file type (Elf32_Half) */ public int e_machine; /* machine type (Elf32_Half) */ public long e_version; /* version number (Elf32_Word) */ - public long e_entry; /* entry point (Elf32_Addr)*/ + public IAddress e_entry; /* entry point (Elf32_Addr)*/ public long e_phoff; /* Program hdr offset (Elf32_Off)*/ public long e_shoff; /* Section hdr offset (Elf32_Off)*/ public long e_flags; /* Processor flags (Elf32_Word)*/ @@ -138,9 +149,30 @@ public class Elf { e_type = efile.readShortE(); e_machine = efile.readShortE(); e_version = efile.readIntE(); - e_entry = efile.readIntE(); + switch (e_ident[ELFhdr.EI_CLASS]) + { + case ELFhdr.ELFCLASS32: + { + byte[] addrArray = new byte[ELF32_ADDR_SIZE]; + efile.readFullyE(addrArray); + e_entry = new Addr32(addrArray); e_phoff = efile.readIntE(); e_shoff = efile.readIntE(); + } + break; + case ELFhdr.ELFCLASS64: + { + byte[] addrArray = new byte[ELF64_ADDR_SIZE]; + efile.readFullyE(addrArray); + e_entry = new Addr64(addrArray); + e_phoff = readUnsignedLong(efile); + e_shoff = readUnsignedLong(efile); + } + break; + case ELFhdr.ELFCLASSNONE: + default: + throw new IOException("Unknown ELF class " + e_ident[ELFhdr.EI_CLASS]); + } e_flags = efile.readIntE(); e_ehsize = efile.readShortE(); e_phentsize = efile.readShortE(); @@ -163,9 +195,30 @@ public class Elf { 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; + switch (e_ident[ELFhdr.EI_CLASS]) + { + case ELFhdr.ELFCLASS32: + { + byte[] addrArray = new byte[ELF32_ADDR_SIZE]; + System.arraycopy(bytes, offset, addrArray, 0, ELF32_ADDR_SIZE); offset += ELF32_ADDR_SIZE; + e_entry = new Addr32(addrArray); + e_phoff = makeInt(bytes, offset, isle); offset += ELF32_OFF_SIZE; + e_shoff = makeInt(bytes, offset, isle); offset += ELF32_OFF_SIZE; + } + break; + case ELFhdr.ELFCLASS64: + { + byte[] addrArray = new byte[ELF64_ADDR_SIZE]; + System.arraycopy(bytes, offset, addrArray, 0, ELF64_ADDR_SIZE); offset += ELF64_ADDR_SIZE; + e_entry = new Addr64(addrArray); + e_phoff = makeUnsignedLong(bytes, offset, isle); offset += ELF64_OFF_SIZE; + e_shoff = makeUnsignedLong(bytes, offset, isle); offset += ELF64_OFF_SIZE; + } + break; + case ELFhdr.ELFCLASSNONE: + default: + throw new IOException("Unknown ELF class " + e_ident[ELFhdr.EI_CLASS]); + } e_flags = makeInt(bytes, offset, isle); offset += 4; e_ehsize = makeShort(bytes, offset, isle); offset += 2; e_phentsize = makeShort(bytes, offset, isle); offset += 2; @@ -194,6 +247,38 @@ public class Elf { return ((val[offset + 0] << 24) + (val[offset + 1] << 16) + (val[offset + 2] << 8) + val[offset + 3]); } + private final long makeLong(byte [] val, int offset, boolean isle) throws IOException + { + long result = 0; + int shift = 0; + if ( isle ) + for(int i=7; i >= 0; i-- ) + { + shift = i*8; + result += ( ((long)val[offset + i]) << shift ) & ( 0xffL << shift ); + } + else + for(int i=0; i <= 7; i++ ) + { + shift = (7-i)*8; + result += ( ((long)val[offset + i]) << shift ) & ( 0xffL << shift ); + } + return result; + } + + private final long makeUnsignedLong(byte [] val, int offset, boolean isle) throws IOException + { + long result = makeLong(val,offset,isle); + if(result < 0) + { + throw new IOException( "Maximal file offset is " + Long.toHexString(Long.MAX_VALUE) + + " given offset is " + Long.toHexString(result)); + } + return result; + + } + + } @@ -222,7 +307,7 @@ public class Elf { public long sh_name; public long sh_type; public long sh_flags; - public long sh_addr; + public IAddress sh_addr; public long sh_offset; public long sh_size; public long sh_link; @@ -301,9 +386,9 @@ public class Elf { public final static int SHN_XINDEX = 0xffffffff; public final static int SHN_HIRESERVE = 0xffffffff; - + /*NOTE: 64 bit and 32 bit ELF sections has different order*/ public long st_name; - public long st_value; + public IAddress st_value; public long st_size; public short st_info; public short st_other; @@ -326,6 +411,7 @@ public class Elf { } public int compareTo(Object obj) { + /* long thisVal = 0; long anotherVal = 0; if ( obj instanceof Symbol ) { @@ -338,6 +424,8 @@ public class Elf { thisVal = this.st_value; } return (thisVal 0 ) return symbols[ndx]; if ( ndx == -1 ) { @@ -882,7 +1101,7 @@ public class Elf { ndx = -ndx - 1; return symbols[ndx-1]; } - + /* public long swapInt( long val ) { if ( ehdr.e_ident[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB ) { short tmp[] = new short[4]; @@ -904,8 +1123,19 @@ public class Elf { } return val; } - +*/ public String getFilename() { return file; } + + private final long readUnsignedLong(ERandomAccessFile file) throws IOException + { + long result = file.readLongE(); + if(result < 0) + { + throw new IOException( "Maximal file offset is " + Long.toHexString(Long.MAX_VALUE) + + " given offset is " + Long.toHexString(result)); + } + return result; + } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java index 55b669cbe31..a20a245e4b6 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java @@ -120,6 +120,7 @@ public class ElfBinaryObject extends BinaryObjectAdapter { info.isLittleEndian = attribute.isLittleEndian(); info.hasDebug = attribute.hasDebug(); info.cpu = attribute.getCPU(); + info.addressFactory = attribute.getAddressFactory(); } protected void loadSymbols(ElfHelper helper) throws IOException { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java index 0e029287c26..20d5e54c0db 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java @@ -11,8 +11,10 @@ package org.eclipse.cdt.utils.elf.parser; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.math.BigInteger; import java.util.List; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.utils.Addr2line; import org.eclipse.cdt.utils.CPPFilt; import org.eclipse.cdt.utils.Objdump; @@ -124,7 +126,7 @@ public class GNUElfBinaryObject extends ElfBinaryObject { cppfilt = null; } } - long addr = array[i].st_value; + IAddress addr = array[i].st_value; long size = array[i].st_size; if (addr2line != null) { try { @@ -133,7 +135,7 @@ public class GNUElfBinaryObject extends ElfBinaryObject { // the file. IPath file = (filename != null && !filename.equals("??")) ? new Path(filename) : Path.EMPTY; //$NON-NLS-1$ int startLine = addr2line.getLineNumber(addr); - int endLine = addr2line.getLineNumber(addr + size - 1); + int endLine = addr2line.getLineNumber(addr.add(BigInteger.valueOf(size - 1))); list.add(new GNUSymbol(this, name, type, addr, size, file, startLine, endLine)); } catch (IOException e) { addr2line = null; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUSymbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUSymbol.java index 141c39cb4c9..136bea42a02 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUSymbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/GNUSymbol.java @@ -11,19 +11,21 @@ package org.eclipse.cdt.utils.elf.parser; import java.io.IOException; +import java.math.BigInteger; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.utils.Addr2line; import org.eclipse.cdt.utils.Symbol; import org.eclipse.core.runtime.IPath; public class GNUSymbol extends Symbol { - public GNUSymbol(GNUElfBinaryObject binary, String name, int type, long addr, long size, IPath sourceFile, int startLine, int endLine) { + public GNUSymbol(GNUElfBinaryObject binary, String name, int type, IAddress addr, long size, IPath sourceFile, int startLine, int endLine) { super(binary, name, type, addr, size, sourceFile, startLine, endLine); // TODO Auto-generated constructor stub } - public GNUSymbol(GNUElfBinaryObject binary, String name, int type, long addr, long size) { + public GNUSymbol(GNUElfBinaryObject binary, String name, int type, IAddress addr, long size) { super(binary, name, type, addr, size); } @@ -35,7 +37,7 @@ public class GNUSymbol extends Symbol { Addr2line addr2line = ((GNUElfBinaryObject)binary).getAddr2line(true); if (addr2line != null) { try { - return addr2line.getLineNumber(getAddress() + offset); + return addr2line.getLineNumber(getAddress().add(BigInteger.valueOf(offset))); } catch (IOException e) { // ignore } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/ARMember.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/ARMember.java index 458cf3aa710..7d7cd09e0e9 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/ARMember.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/ARMember.java @@ -18,6 +18,7 @@ import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.CPPFilt; import org.eclipse.cdt.utils.Symbol; import org.eclipse.cdt.utils.macho.AR; @@ -72,7 +73,7 @@ public class ARMember extends MachOBinaryObject { protected void addSymbols(MachO.Symbol[] array, int type, Addr2line addr2line, CPPFilt cppfilt, List list) { for (int i = 0; i < array.length; i++) { - list.add(new Symbol(this, array[i].toString(), type, array[i].n_value, 4)); + list.add(new Symbol(this, array[i].toString(), type, new Addr32(array[i].n_value), 4)); } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java index 1089635ce72..22803d78b36 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java @@ -18,6 +18,7 @@ import java.util.List; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.BinaryObjectAdapter; import org.eclipse.cdt.utils.CPPFilt; import org.eclipse.cdt.utils.Symbol; @@ -161,7 +162,7 @@ public class MachOBinaryObject extends BinaryObjectAdapter { int size = 0; String filename = array[i].getFilename(); IPath filePath = (filename != null) ? new Path(filename) : null; //$NON-NLS-1$ - list.add(new Symbol(this, name, type, array[i].n_value, size, filePath, array[i].getLineNumber(addr), array[i].getLineNumber(addr + size - 1))); + list.add(new Symbol(this, name, type, new Addr32(array[i].n_value), size, filePath, array[i].getLineNumber(addr), array[i].getLineNumber(addr + size - 1))); } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/ARMember.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/ARMember.java index 83f5828ee93..11b7794d423 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/ARMember.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/ARMember.java @@ -18,12 +18,12 @@ import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser.ISymbol; -import org.eclipse.core.runtime.IPath; - +import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.CPPFilt; import org.eclipse.cdt.utils.Symbol; import org.eclipse.cdt.utils.som.AR; import org.eclipse.cdt.utils.som.SOM; +import org.eclipse.core.runtime.IPath; /** * A member of a SOM archive @@ -61,7 +61,7 @@ public class ARMember extends SOMBinaryObject { cppfilt = null; } } - Symbol sym = new Symbol(this, name, peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE, peSyms[i].symbol_value, 1); + Symbol sym = new Symbol(this, name, peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE, new Addr32(peSyms[i].symbol_value), 1); list.add(sym); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java index 769a495cbed..b9b155ff7c7 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java @@ -13,19 +13,21 @@ package org.eclipse.cdt.utils.som.parser; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.ISymbol; import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.BinaryObjectAdapter; import org.eclipse.cdt.utils.CPPFilt; import org.eclipse.cdt.utils.Objdump; import org.eclipse.cdt.utils.som.SOM; -import org.eclipse.cdt.utils.som.parser.SOMParser; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; @@ -162,7 +164,7 @@ public class SOMBinaryObject extends BinaryObjectAdapter { continue; } int type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE; - int addr = peSyms[i].symbol_value; + IAddress addr = new Addr32(peSyms[i].symbol_value); int size = 4; if (cppfilt != null) { try { @@ -181,7 +183,7 @@ public class SOMBinaryObject extends BinaryObjectAdapter { IPath file = filename != null ? new Path(filename) : Path.EMPTY; int startLine = addr2line.getLineNumber(addr); - int endLine = addr2line.getLineNumber(addr + size - 1); + int endLine = addr2line.getLineNumber(addr.add(BigInteger.valueOf(size - 1))); list.add(new SomSymbol(this, name, type, addr, size, file, startLine, endLine)); } catch (IOException e) { addr2line = null; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java index 05eb728a45b..3e202a560cc 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java @@ -11,7 +11,9 @@ package org.eclipse.cdt.utils.som.parser; import java.io.IOException; +import java.math.BigInteger; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.utils.Addr2line; import org.eclipse.cdt.utils.BinaryObjectAdapter; import org.eclipse.cdt.utils.Symbol; @@ -34,7 +36,7 @@ public class SomSymbol extends Symbol { * @param startLine * @param endLine */ - public SomSymbol(BinaryObjectAdapter binary, String name, int type, long addr, long size, IPath sourceFile, int startLine, int endLine) { + public SomSymbol(BinaryObjectAdapter binary, String name, int type, IAddress addr, long size, IPath sourceFile, int startLine, int endLine) { super(binary, name, type, addr, size, sourceFile, startLine, endLine); // TODO Auto-generated constructor stub } @@ -46,7 +48,7 @@ public class SomSymbol extends Symbol { * @param addr * @param size */ - public SomSymbol(BinaryObjectAdapter binary, String name, int type, long addr, long size) { + public SomSymbol(BinaryObjectAdapter binary, String name, int type, IAddress addr, long size) { super(binary, name, type, addr, size); // TODO Auto-generated constructor stub } @@ -59,7 +61,7 @@ public class SomSymbol extends Symbol { Addr2line addr2line = ((SOMBinaryObject)binary).getAddr2line(true); if (addr2line != null) { try { - return addr2line.getLineNumber(getAddress() + offset); + return addr2line.getLineNumber(getAddress().add(BigInteger.valueOf(offset))); } catch (IOException e) { // ignore } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/ARMember.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/ARMember.java index 7006d0e24d3..e3530dba688 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/ARMember.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/ARMember.java @@ -18,6 +18,7 @@ import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.CPPFilt; import org.eclipse.cdt.utils.Symbol; import org.eclipse.cdt.utils.xcoff.AR; @@ -87,7 +88,7 @@ public class ARMember extends XCOFFBinaryObject { cppfilt = null; } } - Symbol sym = new Symbol(this, name, peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE, peSyms[i].n_value, 1); + Symbol sym = new Symbol(this, name, peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE, new Addr32(peSyms[i].n_value), 1); list.add(sym); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java index ec9eb3d6971..918713776e2 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java @@ -11,14 +11,17 @@ package org.eclipse.cdt.utils.xcoff.parser; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.ISymbol; import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.cdt.utils.Addr32; import org.eclipse.cdt.utils.BinaryObjectAdapter; import org.eclipse.cdt.utils.CPPFilt; import org.eclipse.cdt.utils.Objdump; @@ -164,7 +167,7 @@ public class XCOFFBinaryObject extends BinaryObjectAdapter { continue; } int type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE; - int addr = peSyms[i].n_value; + IAddress addr = new Addr32(peSyms[i].n_value); int size = 4; if (cppfilt != null) { try { @@ -184,7 +187,7 @@ public class XCOFFBinaryObject extends BinaryObjectAdapter { IPath file = filename != null ? new Path(filename) : Path.EMPTY; int startLine = addr2line.getLineNumber(addr); - int endLine = addr2line.getLineNumber(addr + size - 1); + int endLine = addr2line.getLineNumber(addr.add(BigInteger.valueOf(size - 1))); list.add(new XCoffSymbol(this, name, type, addr, size, file, startLine, endLine)); } catch (IOException e) { addr2line = null; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCoffSymbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCoffSymbol.java index e23312582c5..f062e85d44e 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCoffSymbol.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/xcoff/parser/XCoffSymbol.java @@ -7,7 +7,9 @@ package org.eclipse.cdt.utils.xcoff.parser; import java.io.IOException; +import java.math.BigInteger; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.utils.Addr2line; import org.eclipse.cdt.utils.BinaryObjectAdapter; import org.eclipse.cdt.utils.Symbol; @@ -32,7 +34,7 @@ public class XCoffSymbol extends Symbol { * @param startLine * @param endLine */ - public XCoffSymbol(BinaryObjectAdapter binary, String name, int type, long addr, long size, IPath sourceFile, int startLine, + public XCoffSymbol(BinaryObjectAdapter binary, String name, int type, IAddress addr, long size, IPath sourceFile, int startLine, int endLine) { super(binary, name, type, addr, size, sourceFile, startLine, endLine); // TODO Auto-generated constructor stub @@ -45,7 +47,7 @@ public class XCoffSymbol extends Symbol { * @param addr * @param size */ - public XCoffSymbol(BinaryObjectAdapter binary, String name, int type, long addr, long size) { + public XCoffSymbol(BinaryObjectAdapter binary, String name, int type, IAddress addr, long size) { super(binary, name, type, addr, size); // TODO Auto-generated constructor stub } @@ -58,7 +60,7 @@ public class XCoffSymbol extends Symbol { Addr2line addr2line = ((XCOFFBinaryObject)binary).getAddr2line(true); if (addr2line != null) { try { - return addr2line.getLineNumber(getAddress() + offset); + return addr2line.getLineNumber(getAddress().add(BigInteger.valueOf(offset))); } catch (IOException e) { // ignore }