1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-28 11:25:35 +02:00

faster IArchive

This commit is contained in:
David Inglis 2003-02-26 21:01:28 +00:00
parent 7f7de54b77
commit 6940e686c7
6 changed files with 304 additions and 356 deletions

View file

@ -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:

View file

@ -15,7 +15,6 @@ 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);

View file

@ -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");

View file

@ -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) {

View file

@ -28,11 +28,9 @@ 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;
@ -44,9 +42,9 @@ public class ElfBinaryFile extends PlatformObject implements IBinaryFile,
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();
}
@ -164,19 +162,19 @@ 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;
case Attribute.ELF_TYPE_SHLIB:
case Attribute.ELF_TYPE_SHLIB :
type = IBinaryFile.SHARED;
break;
case Attribute.ELF_TYPE_OBJ:
case Attribute.ELF_TYPE_OBJ :
type = IBinaryFile.OBJECT;
break;
case Attribute.ELF_TYPE_CORE:
case Attribute.ELF_TYPE_CORE :
type = IBinaryFile.CORE;
break;
}
@ -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,25 +204,11 @@ 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;
if (file != null && header != 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;
}
}
stream = new ByteArrayInputStream(header.getObjectData());
} catch (IOException e) {
}
if (ar != null) {
ar.dispose();
}
}
} else if (file != null && file.exists()) {
try {
stream = file.getContents();
@ -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();
@ -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) {
@ -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.
if (header == null) {
sym.filename = array[i].getFilename();
sym.lineno = array[i].getFuncLineNumber();
}
} catch (IOException e) {
//e.printStackTrace();
}

View file

@ -10,7 +10,6 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Vector;
/**
* The <code>AR</code> class is used for parsing standard ELF archive (ar) files.
*
@ -26,27 +25,20 @@ public class AR {
protected long strtbl_pos = -1;
private ARHeader[] headers;
public void dispose() {
try
{
if (efile != null)
{
try {
if (efile != null) {
efile.close();
efile = null;
}
} catch (IOException e) {
}
catch( IOException e )
{}
}
protected void finalize() throws Throwable {
try
{
try {
dispose();
}
finally
{
} finally {
super.finalize();
}
}
@ -66,17 +58,15 @@ public class AR {
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 );
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.
@ -88,29 +78,24 @@ public class AR {
* @throws IOException
* <code>offset</code> not in string table bounds.
*/
private String nameFromStringTable( long offset ) throws IOException {
StringBuffer name = new StringBuffer( 0 );
private String nameFromStringTable(long offset) throws IOException {
StringBuffer name = new StringBuffer(0);
long pos = efile.getFilePointer();
try
{
if( strtbl_pos != -1 )
{
try {
if (strtbl_pos != -1) {
byte temp;
efile.seek( strtbl_pos + offset );
while( ( temp = efile.readByte() ) != '\n' )
name.append( (char)temp );
efile.seek(strtbl_pos + offset);
while ((temp = efile.readByte()) != '\n')
name.append((char) temp);
}
}
finally
{
efile.seek( pos );
} finally {
efile.seek(pos);
}
return name.toString();
}
/**
* Creates a new archive header object.
*
@ -131,13 +116,13 @@ public class AR {
//
// 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 );
efile.read(object_name);
efile.read(modification_time);
efile.read(uid);
efile.read(gid);
efile.read(mode);
efile.read(size);
efile.read(trailer);
//
// Save this location so we can create the Elf object later.
@ -147,28 +132,22 @@ public class AR {
//
// 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 ) ) );
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)));
//
// If the name is of the format "/<number>", 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 )
{
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) {
}
}
@ -176,9 +155,8 @@ public class AR {
// 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 );
if (len > 2 && this.object_name.charAt(len - 1) == '/') {
this.object_name = this.object_name.substring(0, len - 1);
}
}
@ -193,6 +171,10 @@ public class AR {
return size;
}
public String getArchiveName() {
return filename;
}
/**
* Create an new Elf object for the object file.
*
@ -202,22 +184,29 @@ public class AR {
* @see Elf#Elf( String, long )
*/
public Elf getElf() throws IOException {
return new Elf( filename, elf_offset );
return new Elf(filename, elf_offset);
}
public Elf getElf( boolean filter_on ) throws IOException {
return new Elf( filename, elf_offset, filter_on );
public Elf getElf(boolean filter_on) throws IOException {
return new Elf(filename, elf_offset, filter_on);
}
public byte[] getObjectData() throws IOException {
byte[] temp = new byte[(int)size];
efile.seek( elf_offset );
efile.read( temp );
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;
}
}
/**
* Creates a new <code>AR</code> object from the contents of
* the given file.
@ -225,30 +214,27 @@ public class AR {
* @param filename The file to process.
* @throws IOException The file is not a valid archive.
*/
public AR( String filename ) throws IOException {
public AR(String filename) throws IOException {
this.filename = filename;
efile = new ERandomAccessFile( filename, "r" );
efile = new ERandomAccessFile(filename, "r");
String hdr = efile.readLine();
if( hdr == null || hdr.compareTo( "!<arch>" ) != 0 ) {
if (hdr == null || hdr.compareTo("!<arch>") != 0) {
efile.close();
throw new IOException( "Not a valid archive file." );
throw new IOException("Not a valid archive file.");
}
}
/** Load the headers from the file (if required). */
private void loadHeaders() throws IOException {
if( headers != null )
if (headers != null)
return;
Vector v = new Vector();
try
{
try {
//
// Check for EOF condition
//
while( efile.getFilePointer() < efile.length() )
{
while (efile.getFilePointer() < efile.length()) {
ARHeader header = new ARHeader();
String name = header.getObjectName();
@ -257,32 +243,28 @@ public class AR {
//
// If the name starts with a / it is specical.
//
if( name.charAt( 0 ) != '/' )
v.add( header );
if (name.charAt(0) != '/')
v.add(header);
//
// If the name is "//" then this is the string table section.
//
if( name.compareTo( "//" ) == 0 )
if (name.compareTo("//") == 0)
strtbl_pos = pos;
//
// Compute the location of the next header in the archive.
//
pos += header.getSize();
if( ( pos % 2 ) != 0 )
if ((pos % 2) != 0)
pos++;
efile.seek( pos );
efile.seek(pos);
}
} catch (IOException e) {
}
catch( IOException e )
{
headers = (ARHeader[]) v.toArray(new ARHeader[0]);
}
headers = (ARHeader[])v.toArray( new ARHeader[0] );
}
/**
* Get an array of all the object file headers for this archive.
@ -297,18 +279,14 @@ public class AR {
return headers;
}
private boolean stringInStrings( String str, String[] set ) {
for( int i=0; i<set.length; i++ )
if( str.compareTo( set[i] ) == 0 )
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;
}
public String[] extractFiles( String outdir, String[] names )
throws IOException
{
public String[] extractFiles(String outdir, String[] names) throws IOException {
Vector names_used = new Vector();
String object_name;
int count;
@ -316,31 +294,28 @@ public class AR {
loadHeaders();
count = 0;
for( int i=0; i<headers.length; i++ )
{
for (int i = 0; i < headers.length; i++) {
object_name = headers[i].getObjectName();
if( names != null && !stringInStrings( object_name, names ) )
if (names != null && !stringInStrings(object_name, names))
continue;
object_name = "" + count + "_" + object_name;
count ++;
count++;
byte[] data = headers[i].getObjectData();
File output = new File( outdir, object_name );
names_used.add( object_name );
File output = new File(outdir, object_name);
names_used.add(object_name);
RandomAccessFile rfile = new RandomAccessFile( output, "rw" );
rfile.write( data );
RandomAccessFile rfile = new RandomAccessFile(output, "rw");
rfile.write(data);
rfile.close();
}
return (String[])names_used.toArray( new String[0] );
return (String[]) names_used.toArray(new String[0]);
}
public String[] extractFiles( String outdir ) throws IOException {
return extractFiles( outdir, null );
public String[] extractFiles(String outdir) throws IOException {
return extractFiles(outdir, null);
}
}