diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog
index 830d8bc0eab..4477da740c4 100644
--- a/core/org.eclipse.cdt.core/ChangeLog
+++ b/core/org.eclipse.cdt.core/ChangeLog
@@ -1,3 +1,14 @@
+2003-02-26 David Inglis
+ * model/org/eclipse/cdt/internal/core/model/ArchiveContainer.java
+ * model/org/eclipse/cdt/internal/core/model/BinaryContainer.java
+ Remove warning.
+
+ * model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryArchive.java
+ * model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryFile.java
+ * utils/org/eclipse/cdt/utils/elf/AR.java
+ Improve IBinaryObject creation from IArchive (big speed improvment)
+
+
2003-02-24 Alain Magloire
* model/org/eclipse/cdt/internal/core/model/Marker.java:
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ArchiveContainer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ArchiveContainer.java
index d2ea2187aa0..e22639f6bd2 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ArchiveContainer.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ArchiveContainer.java
@@ -15,8 +15,7 @@ import org.eclipse.core.resources.IProject;
public class ArchiveContainer extends Parent implements IArchiveContainer {
CProject cProject;
- private long modificationStamp;
-
+
public ArchiveContainer (CProject cProject) {
super (cProject, null, "lib", CElement.C_CONTAINER);
this.cProject = cProject;
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryContainer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryContainer.java
index 57079d78b4b..26b57407439 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryContainer.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryContainer.java
@@ -19,7 +19,6 @@ import org.eclipse.core.runtime.CoreException;
public class BinaryContainer extends Parent implements IBinaryContainer {
CProject cProject;
- private long modificationStamp;
public BinaryContainer (CProject cProject) {
this (cProject, "bin");
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryArchive.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryArchive.java
index a0102710ff2..d6de29a0f52 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryArchive.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryArchive.java
@@ -45,7 +45,7 @@ public class ElfBinaryArchive extends PlatformObject implements IBinaryArchive {
ar = new AR(location.toOSString());
AR.ARHeader[] headers = ar.getHeaders();
for (int i = 0; i < headers.length; i++) {
- IBinaryObject bin = new ElfBinaryFile(file, headers[i].getObjectName());
+ IBinaryObject bin = new ElfBinaryFile(file, headers[i]);
children.add(bin);
}
} catch (IOException e) {
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryFile.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryFile.java
index 6eb06343dca..81cebdc6bf8 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryFile.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/parser/ElfBinaryFile.java
@@ -4,7 +4,7 @@ package org.eclipse.cdt.internal.core.model.parser;
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
-
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -28,25 +28,23 @@ import org.eclipse.core.runtime.PlatformObject;
/**
*/
-public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
- IBinaryObject, IBinaryExecutable, IBinaryShared {
-
+public class ElfBinaryFile extends PlatformObject implements IBinaryFile, IBinaryObject, IBinaryExecutable, IBinaryShared {
IFile file;
- String objectName;
+ AR.ARHeader header;
long timestamp;
String soname;
String[] needed;
Sizes sizes;
Attribute attribute;
ArrayList symbols;
-
+
public ElfBinaryFile(IFile f) throws IOException {
this(f, null);
}
- public ElfBinaryFile(IFile f, String n) throws IOException {
+ public ElfBinaryFile(IFile f, AR.ARHeader h) throws IOException {
+ header = h;
file = f;
- objectName = n;
loadInformation();
hasChanged();
}
@@ -55,7 +53,7 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile()
*/
public IFile getFile() {
- return file;
+ return file;
}
/**
@@ -155,7 +153,7 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
}
return new String[0];
}
-
+
/**
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType()
*/
@@ -164,21 +162,21 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
Attribute attr = getAttribute();
if (attr != null) {
switch (attribute.getType()) {
- case Attribute.ELF_TYPE_EXE:
+ case Attribute.ELF_TYPE_EXE :
type = IBinaryFile.EXECUTABLE;
- break;
+ break;
- case Attribute.ELF_TYPE_SHLIB:
+ case Attribute.ELF_TYPE_SHLIB :
type = IBinaryFile.SHARED;
- break;
+ break;
- case Attribute.ELF_TYPE_OBJ:
+ case Attribute.ELF_TYPE_OBJ :
type = IBinaryFile.OBJECT;
- break;
-
- case Attribute.ELF_TYPE_CORE:
+ break;
+
+ case Attribute.ELF_TYPE_CORE :
type = IBinaryFile.CORE;
- break;
+ break;
}
}
return type;
@@ -197,7 +195,7 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
} catch (IOException e) {
}
}
- return (ISymbol[])symbols.toArray(new ISymbol[0]);
+ return (ISymbol[]) symbols.toArray(new ISymbol[0]);
}
/**
@@ -206,24 +204,10 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
public InputStream getContents() {
InputStream stream = null;
// Archive ?
- if (file != null && objectName != null) {
- IPath location = file.getLocation();
- if (location != null) {
- AR ar = null;
- try {
- ar = new AR(file.getLocation().toOSString());
- AR.ARHeader[] headers = ar.getHeaders();
- for (int i = 0; i < headers.length; i++) {
- if (objectName.equals(headers[i].getObjectName())) {
- stream = new ByteArrayInputStream(headers[i].getObjectData());
- break;
- }
- }
- } catch (IOException e) {
- }
- if (ar != null) {
- ar.dispose();
- }
+ if (file != null && header != null) {
+ try {
+ stream = new ByteArrayInputStream(header.getObjectData());
+ } catch (IOException e) {
}
} else if (file != null && file.exists()) {
try {
@@ -241,8 +225,8 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
* @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName()
*/
public String getName() {
- if (objectName != null) {
- return objectName;
+ if (header != null) {
+ return header.getObjectName();
}
if (file != null) {
return file.getName();
@@ -273,7 +257,7 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
}
return sizes;
}
-
+
boolean hasChanged() {
long modification = file.getModificationStamp();
boolean changed = modification != timestamp;
@@ -283,30 +267,8 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
protected ElfHelper getElfHelper() throws IOException {
// Archive ?
- if (file != null && objectName != null) {
- IPath location = file.getLocation();
- if (location != null) {
- ElfHelper helper = null;
- AR ar = null;
- try {
- ar = new AR(file.getLocation().toOSString());
- AR.ARHeader[] headers = ar.getHeaders();
- for (int i = 0; i < headers.length; i++) {
- AR.ARHeader hdr = headers[i];
- if (objectName.equals(hdr.getObjectName())) {
- helper = new ElfHelper(hdr.getElf());
- break;
- }
- }
- } finally {
- if (ar != null) {
- ar.dispose();
- }
- }
- if (helper != null) {
- return helper;
- }
- }
+ if (header != null) {
+ return new ElfHelper(header.getElf());
} else if (file != null && file.exists()) {
IPath path = file.getLocation();
if (path == null) {
@@ -331,7 +293,7 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
symbols.trimToSize();
}
}
-
+
private void loadAttributes(ElfHelper helper) throws IOException {
Elf.Dynamic[] sharedlibs = helper.getNeeded();
needed = new String[sharedlibs.length];
@@ -368,8 +330,10 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
try {
// This can fail if we use addr2line
// but we can safely ignore the error.
- sym.filename = array[i].getFilename();
- sym.lineno = array[i].getFuncLineNumber();
+ if (header == null) {
+ sym.filename = array[i].getFilename();
+ sym.lineno = array[i].getFuncLineNumber();
+ }
} catch (IOException e) {
//e.printStackTrace();
}
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java
index ba3292099e8..98df6c982a2 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/AR.java
@@ -10,7 +10,6 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Vector;
-
/**
* The AR
class is used for parsing standard ELF archive (ar) files.
*
@@ -21,326 +20,302 @@ import java.util.Vector;
*/
public class AR {
- protected String filename;
- protected ERandomAccessFile efile;
- protected long strtbl_pos = -1;
- private ARHeader[] headers;
+ protected String filename;
+ protected ERandomAccessFile efile;
+ protected long strtbl_pos = -1;
+ private ARHeader[] headers;
+ public void dispose() {
+ try {
+ if (efile != null) {
+ efile.close();
+ efile = null;
+ }
+ } catch (IOException e) {
+ }
+ }
- public void dispose() {
- try
- {
- if (efile != null)
- {
- efile.close();
- efile = null;
- }
- }
- catch( IOException e )
- {}
- }
+ protected void finalize() throws Throwable {
+ try {
+ dispose();
+ } finally {
+ super.finalize();
+ }
+ }
- protected void finalize() throws Throwable {
- try
- {
- dispose();
- }
- finally
- {
- super.finalize();
- }
- }
+ /**
+ * The ARHeader
class is used to store the per-object file
+ * archive headers. It can also create an Elf object for inspecting
+ * the object file data.
+ */
+ public class ARHeader {
- /**
- * The ARHeader
class is used to store the per-object file
- * archive headers. It can also create an Elf object for inspecting
- * the object file data.
- */
- public class ARHeader {
+ private String object_name;
+ private String modification_time;
+ private String uid;
+ private String gid;
+ private String mode;
+ private long size;
+ private long elf_offset;
- private String object_name;
- private String modification_time;
- private String uid;
- private String gid;
- private String mode;
- private long size;
- private long elf_offset;
+ /**
+ * Remove the padding from the archive header strings.
+ */
+ private String removeBlanks(String str) {
+ while (str.charAt(str.length() - 1) == ' ')
+ str = str.substring(0, str.length() - 1);
+ return str;
+ }
+ /**
+ * Look up the name stored in the archive's string table based
+ * on the offset given.
+ *
+ * Maintains efile
file location.
+ *
+ * @param offset
+ * Offset into the string table for first character of the name.
+ * @throws IOException
+ * offset
not in string table bounds.
+ */
+ private String nameFromStringTable(long offset) throws IOException {
+ StringBuffer name = new StringBuffer(0);
+ long pos = efile.getFilePointer();
- /**
- * Remove the padding from the archive header strings.
- */
- private String removeBlanks( String str ) {
- while( str.charAt( str.length() - 1 ) == ' ' )
- str = str.substring( 0, str.length() - 1 );
- return str;
- }
+ try {
+ if (strtbl_pos != -1) {
+ byte temp;
+ efile.seek(strtbl_pos + offset);
+ while ((temp = efile.readByte()) != '\n')
+ name.append((char) temp);
+ }
+ } finally {
+ efile.seek(pos);
+ }
+ return name.toString();
+ }
- /**
- * Look up the name stored in the archive's string table based
- * on the offset given.
- *
- * Maintains efile
file location.
- *
- * @param offset
- * Offset into the string table for first character of the name.
- * @throws IOException
- * offset
not in string table bounds.
- */
- private String nameFromStringTable( long offset ) throws IOException {
- StringBuffer name = new StringBuffer( 0 );
- long pos = efile.getFilePointer();
+ /**
+ * Creates a new archive header object.
+ *
+ * Assumes that efile is already at the correct location in the file.
+ *
+ * @throws IOException
+ * There was an error processing the header data from the file.
+ */
+ public ARHeader() throws IOException {
+ byte[] object_name = new byte[16];
+ byte[] modification_time = new byte[12];
+ byte[] uid = new byte[6];
+ byte[] gid = new byte[6];
+ byte[] mode = new byte[8];
+ byte[] size = new byte[10];
+ byte[] trailer = new byte[2];
- try
- {
- if( strtbl_pos != -1 )
- {
- byte temp;
- efile.seek( strtbl_pos + offset );
- while( ( temp = efile.readByte() ) != '\n' )
- name.append( (char)temp );
- }
- }
- finally
- {
- efile.seek( pos );
- }
+ //
+ // Read in the archive header data. Fixed sizes.
+ //
+ efile.read(object_name);
+ efile.read(modification_time);
+ efile.read(uid);
+ efile.read(gid);
+ efile.read(mode);
+ efile.read(size);
+ efile.read(trailer);
- return name.toString();
- }
+ //
+ // Save this location so we can create the Elf object later.
+ //
+ elf_offset = efile.getFilePointer();
+ //
+ // Convert the raw bytes into strings and numbers.
+ //
+ this.object_name = removeBlanks(new String(object_name));
+ this.modification_time = new String(modification_time);
+ this.uid = new String(uid);
+ this.gid = new String(gid);
+ this.mode = new String(mode);
+ this.size = Long.parseLong(removeBlanks(new String(size)));
- /**
- * Creates a new archive header object.
- *
- * Assumes that efile is already at the correct location in the file.
- *
- * @throws IOException
- * There was an error processing the header data from the file.
- */
- public ARHeader() throws IOException {
- byte[] object_name = new byte[16];
- byte[] modification_time = new byte[12];
- byte[] uid = new byte[6];
- byte[] gid = new byte[6];
- byte[] mode = new byte[8];
- byte[] size = new byte[10];
- byte[] trailer = new byte[2];
+ //
+ // If the name is of the format "/", get name from the
+ // string table.
+ //
+ if (strtbl_pos != -1 && this.object_name.length() > 1 && this.object_name.charAt(0) == '/') {
+ try {
+ long offset = Long.parseLong(this.object_name.substring(1));
+ this.object_name = nameFromStringTable(offset);
+ } catch (java.lang.Exception e) {
+ }
+ }
- //
- // Read in the archive header data. Fixed sizes.
- //
- efile.read( object_name );
- efile.read( modification_time );
- efile.read( uid );
- efile.read( gid );
- efile.read( mode );
- efile.read( size );
- efile.read( trailer );
+ //
+ // Strip the trailing / from the object name.
+ //
+ int len = this.object_name.length();
+ if (len > 2 && this.object_name.charAt(len - 1) == '/') {
+ this.object_name = this.object_name.substring(0, len - 1);
+ }
- //
- // Save this location so we can create the Elf object later.
- //
- elf_offset = efile.getFilePointer();
+ }
- //
- // Convert the raw bytes into strings and numbers.
- //
- this.object_name = removeBlanks( new String( object_name ) );
- this.modification_time = new String( modification_time );
- this.uid = new String( uid );
- this.gid = new String( gid );
- this.mode = new String( mode );
- this.size = Long.parseLong( removeBlanks( new String( size ) ) );
+ /** Get the name of the object file */
+ public String getObjectName() {
+ return object_name;
+ }
- //
- // If the name is of the format "/", get name from the
- // string table.
- //
- if( strtbl_pos != -1 &&
- this.object_name.length() > 1 &&
- this.object_name.charAt( 0 ) == '/' )
- {
- try
- {
- long offset = Long.parseLong( this.object_name.substring( 1 ) );
- this.object_name = nameFromStringTable( offset );
- }
- catch( java.lang.Exception e )
- {
- }
- }
+ /** Get the size of the object file . */
+ public long getSize() {
+ return size;
+ }
+
+ public String getArchiveName() {
+ return filename;
+ }
- //
- // Strip the trailing / from the object name.
- //
- int len = this.object_name.length();
- if( len > 2 && this.object_name.charAt( len - 1 ) == '/' )
- {
- this.object_name = this.object_name.substring( 0, len - 1 );
- }
+ /**
+ * Create an new Elf object for the object file.
+ *
+ * @throws IOException
+ * Not a valid Elf object file.
+ * @return A new Elf object.
+ * @see Elf#Elf( String, long )
+ */
+ public Elf getElf() throws IOException {
+ return new Elf(filename, elf_offset);
+ }
- }
+ public Elf getElf(boolean filter_on) throws IOException {
+ return new Elf(filename, elf_offset, filter_on);
+ }
- /** Get the name of the object file */
- public String getObjectName() {
- return object_name;
- }
+ public byte[] getObjectData() throws IOException {
+ byte[] temp = new byte[(int) size];
+ if (efile != null) {
+ efile.seek(elf_offset);
+ efile.read(temp);
+ } else {
+ efile = new ERandomAccessFile(filename, "r");
+ efile.seek(elf_offset);
+ efile.read(temp);
+ efile.close();
+ efile = null;
+ }
+ return temp;
+ }
+ }
- /** Get the size of the object file . */
- public long getSize() {
- return size;
- }
+ /**
+ * Creates a new AR
object from the contents of
+ * the given file.
+ *
+ * @param filename The file to process.
+ * @throws IOException The file is not a valid archive.
+ */
+ public AR(String filename) throws IOException {
+ this.filename = filename;
+ efile = new ERandomAccessFile(filename, "r");
+ String hdr = efile.readLine();
+ if (hdr == null || hdr.compareTo("!") != 0) {
+ efile.close();
+ throw new IOException("Not a valid archive file.");
+ }
+ }
- /**
- * Create an new Elf object for the object file.
- *
- * @throws IOException
- * Not a valid Elf object file.
- * @return A new Elf object.
- * @see Elf#Elf( String, long )
- */
- public Elf getElf() throws IOException {
- return new Elf( filename, elf_offset );
- }
+ /** Load the headers from the file (if required). */
+ private void loadHeaders() throws IOException {
+ if (headers != null)
+ return;
- public Elf getElf( boolean filter_on ) throws IOException {
- return new Elf( filename, elf_offset, filter_on );
- }
+ Vector v = new Vector();
+ try {
+ //
+ // Check for EOF condition
+ //
+ while (efile.getFilePointer() < efile.length()) {
+ ARHeader header = new ARHeader();
+ String name = header.getObjectName();
- public byte[] getObjectData() throws IOException {
- byte[] temp = new byte[(int)size];
- efile.seek( elf_offset );
- efile.read( temp );
- return temp;
- }
- }
+ long pos = efile.getFilePointer();
+ //
+ // If the name starts with a / it is specical.
+ //
+ if (name.charAt(0) != '/')
+ v.add(header);
- /**
- * Creates a new AR
object from the contents of
- * the given file.
- *
- * @param filename The file to process.
- * @throws IOException The file is not a valid archive.
- */
- public AR( String filename ) throws IOException {
- this.filename = filename;
- efile = new ERandomAccessFile( filename, "r" );
- String hdr = efile.readLine();
- if( hdr == null || hdr.compareTo( "!" ) != 0 ) {
- efile.close();
- throw new IOException( "Not a valid archive file." );
- }
- }
+ //
+ // If the name is "//" then this is the string table section.
+ //
+ if (name.compareTo("//") == 0)
+ strtbl_pos = pos;
+ //
+ // Compute the location of the next header in the archive.
+ //
+ pos += header.getSize();
+ if ((pos % 2) != 0)
+ pos++;
- /** Load the headers from the file (if required). */
- private void loadHeaders() throws IOException {
- if( headers != null )
- return;
+ efile.seek(pos);
+ }
+ } catch (IOException e) {
+ }
+ headers = (ARHeader[]) v.toArray(new ARHeader[0]);
+ }
- Vector v = new Vector();
- try
- {
- //
- // Check for EOF condition
- //
- while( efile.getFilePointer() < efile.length() )
- {
- ARHeader header = new ARHeader();
- String name = header.getObjectName();
+ /**
+ * Get an array of all the object file headers for this archive.
+ *
+ * @throws IOException
+ * Unable to process the archive file.
+ * @return An array of headers, one for each object within the archive.
+ * @see ARHeader
+ */
+ public ARHeader[] getHeaders() throws IOException {
+ loadHeaders();
+ return headers;
+ }
- long pos = efile.getFilePointer();
+ private boolean stringInStrings(String str, String[] set) {
+ for (int i = 0; i < set.length; i++)
+ if (str.compareTo(set[i]) == 0)
+ return true;
+ return false;
+ }
- //
- // If the name starts with a / it is specical.
- //
- if( name.charAt( 0 ) != '/' )
- v.add( header );
+ public String[] extractFiles(String outdir, String[] names) throws IOException {
+ Vector names_used = new Vector();
+ String object_name;
+ int count;
- //
- // If the name is "//" then this is the string table section.
- //
- if( name.compareTo( "//" ) == 0 )
- strtbl_pos = pos;
+ loadHeaders();
+ count = 0;
+ for (int i = 0; i < headers.length; i++) {
+ object_name = headers[i].getObjectName();
+ if (names != null && !stringInStrings(object_name, names))
+ continue;
- //
- // Compute the location of the next header in the archive.
- //
- pos += header.getSize();
- if( ( pos % 2 ) != 0 )
- pos++;
+ object_name = "" + count + "_" + object_name;
+ count++;
- efile.seek( pos );
- }
- }
- catch( IOException e )
- {
- }
- headers = (ARHeader[])v.toArray( new ARHeader[0] );
- }
+ byte[] data = headers[i].getObjectData();
+ File output = new File(outdir, object_name);
+ names_used.add(object_name);
+ RandomAccessFile rfile = new RandomAccessFile(output, "rw");
+ rfile.write(data);
+ rfile.close();
+ }
- /**
- * Get an array of all the object file headers for this archive.
- *
- * @throws IOException
- * Unable to process the archive file.
- * @return An array of headers, one for each object within the archive.
- * @see ARHeader
- */
- public ARHeader[] getHeaders() throws IOException {
- loadHeaders();
- return headers;
- }
-
-
- private boolean stringInStrings( String str, String[] set ) {
- for( int i=0; i