1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

fixed bug with mips dyn section reading

new method
cleanup
This commit is contained in:
David Inglis 2003-05-28 12:59:08 +00:00
parent 1ce9ba9ea0
commit 8ab6e1bb4c
3 changed files with 360 additions and 419 deletions

View file

@ -1,3 +1,12 @@
2003-05-29 David Inglis
* utils/org/eclipse/cdt/utils/elf/Elf.java
fixed toString buf for Sestion.
added findSesctionByName() method
fixed bug where reading DYN section would fail for mips
* utils/org/eclipse/cdt/utils/elf/ElfHelper.java
use new findSectionByName.
cleaup
2003-04-29 Alain Magloire 2003-04-29 Alain Magloire
* model/org/eclipse/cdt/internal/core/model/parser/PEParser.java (getBinary): * model/org/eclipse/cdt/internal/core/model/parser/PEParser.java (getBinary):

View file

@ -139,6 +139,8 @@ public class Elf {
public final static int SHT_SHLIB = 10; public final static int SHT_SHLIB = 10;
public final static int SHT_DYNSYM = 11; public final static int SHT_DYNSYM = 11;
public final static int SHT_LOPROC = 0x70000000;
/* sh_flags */ /* sh_flags */
public final static int SHF_WRITE = 1; public final static int SHF_WRITE = 1;
public final static int SHF_ALLOC = 2; public final static int SHF_ALLOC = 2;
@ -173,7 +175,7 @@ public class Elf {
efile.read(section_strtab); efile.read(section_strtab);
} }
int str_size = 0; int str_size = 0;
if ( sh_name > sh_size || ( sh_name + str_size + 1) > section_strtab.length) { if ( sh_name > section_strtab.length) {
return EMPTY_STRING; return EMPTY_STRING;
} }
while( section_strtab[(int)sh_name + str_size] != 0) while( section_strtab[(int)sh_name + str_size] != 0)
@ -483,6 +485,8 @@ public class Elf {
} }
public class Dynamic { public class Dynamic {
public final static int DYN_ENT_SIZE = 8;
public final static int DT_NULL = 0; public final static int DT_NULL = 0;
public final static int DT_NEEDED = 1; public final static int DT_NEEDED = 1;
public final static int DT_PLTRELSZ = 2; public final static int DT_PLTRELSZ = 2;
@ -501,7 +505,6 @@ public class Elf {
public final static int DT_RPATH = 15; public final static int DT_RPATH = 15;
public long d_tag; public long d_tag;
public long d_val; public long d_val;
private Section section; private Section section;
private String name; private String name;
@ -538,16 +541,15 @@ public class Elf {
} }
ArrayList dynList = new ArrayList(); ArrayList dynList = new ArrayList();
efile.seek(section.sh_offset); efile.seek(section.sh_offset);
if (section.sh_entsize == 0) { int off = 0;
// We must assume the section is a table ignoring the sh_entsize as it is not
// set for MIPS.
while( off < section.sh_size ) {
Dynamic dynEnt = new Dynamic(section, efile.readIntE(), efile.readIntE()); Dynamic dynEnt = new Dynamic(section, efile.readIntE(), efile.readIntE());
if ( dynEnt.d_tag == Dynamic.DT_NULL )
break;
dynList.add(dynEnt); dynList.add(dynEnt);
} else { off+= Dynamic.DYN_ENT_SIZE;
for (int i = 0; i < section.sh_size / section.sh_entsize; i++ ) {
Dynamic dynEnt = new Dynamic(section, efile.readIntE(), efile.readIntE());
if ( dynEnt.d_tag == Dynamic.DT_NULL )
break;
dynList.add(dynEnt);
}
} }
return (Dynamic[])dynList.toArray(new Dynamic[0]); return (Dynamic[])dynList.toArray(new Dynamic[0]);
} }
@ -726,6 +728,17 @@ public class Elf {
super.finalize(); super.finalize();
} }
} }
public Section getSectionByName(String name) throws IOException {
if ( sections == null )
getSections();
for( int i = 0; i < sections.length; i++) {
if ( sections[i].toString().equals(name)) {
return sections[i];
}
}
return null;
}
public Section[] getSections(int type) throws IOException { public Section[] getSections(int type) throws IOException {
if ( sections == null ) if ( sections == null )

View file

@ -10,7 +10,6 @@ import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Vector; import java.util.Vector;
/** /**
* <code>ElfHelper</code> is a wrapper class for the <code>Elf</code> class * <code>ElfHelper</code> is a wrapper class for the <code>Elf</code> class
* to provide higher level API for sorting/searching the ELF data. * to provide higher level API for sorting/searching the ELF data.
@ -19,413 +18,333 @@ import java.util.Vector;
*/ */
public class ElfHelper { public class ElfHelper {
private Elf elf; private Elf elf;
private Elf.ELFhdr hdr; private Elf.ELFhdr hdr;
private Elf.Attribute attrib; private Elf.Attribute attrib;
private Elf.Symbol[] dynsyms; private Elf.Symbol[] dynsyms;
private Elf.Symbol[] symbols; private Elf.Symbol[] symbols;
private Elf.Section[] sections; private Elf.Section[] sections;
private Elf.Dynamic[] dynamics; private Elf.Dynamic[] dynamics;
public void dispose() {
public void dispose() { if (elf != null) {
if( elf != null ) elf.dispose();
{ elf = null;
elf.dispose(); }
elf = null; }
}
} public class Sizes {
public long text;
public class Sizes { public long data;
public long text; public long bss;
public long data; public long total;
public long bss; public Sizes(long t, long d, long b) {
public long total; text = t;
public Sizes( long t, long d, long b ) { data = d;
text = t; bss = b;
data = d; total = text + data + bss;
bss = b; }
total = text+data+bss; }
}
} private void loadSymbols() throws IOException {
if (symbols == null) {
elf.loadSymbols();
private void loadSymbols() throws IOException { symbols = elf.getSymtabSymbols();
if( symbols == null ) dynsyms = elf.getDynamicSymbols();
{
elf.loadSymbols(); if (symbols.length <= 0)
symbols = elf.getSymtabSymbols(); symbols = dynsyms;
dynsyms = elf.getDynamicSymbols(); if (dynsyms.length <= 0)
dynsyms = symbols;
if( symbols.length <= 0 ) }
symbols = dynsyms; }
if( dynsyms.length <= 0 )
dynsyms = symbols; private void loadSections() throws IOException {
} if (sections == null)
} sections = elf.getSections();
}
private void loadSections() throws IOException {
if( sections == null ) private void loadDynamics() throws IOException {
sections = elf.getSections(); if (dynamics == null) {
} dynamics = new Elf.Dynamic[0];
Elf.Section dynSect = elf.getSectionByName(".dynamic");
if (dynSect != null) {
private void loadDynamics() throws IOException { dynamics = elf.getDynamicSections(dynSect);
loadSections(); }
if( dynamics == null ) }
{ }
dynamics = new Elf.Dynamic[0];
for( int i=0; i<sections.length; i++ ) /** Common code used by all constructors */
{ private void commonSetup() throws IOException {
if( sections[i].sh_type == Elf.Section.SHT_DYNAMIC ) hdr = elf.getELFhdr();
{ attrib = elf.getAttributes();
dynamics = elf.getDynamicSections( sections[i] ); }
break;
} /**
} * Create a new <code>ElfHelper</code> using an existing <code>Elf</code>
} * object.
} * @param elf An existing Elf object to wrap.
* @throws IOException Error processing the Elf file.
*/
/** Common code used by all constructors */ public ElfHelper(Elf elf) throws IOException {
private void commonSetup() throws IOException { this.elf = elf;
hdr = elf.getELFhdr(); commonSetup();
attrib = elf.getAttributes(); }
}
/**
/** * Create a new <code>ElfHelper</code> based on the given filename.
* Create a new <code>ElfHelper</code> using an existing <code>Elf</code> *
* object. * @param filename The file to use for creating a new Elf object.
* @param elf An existing Elf object to wrap. * @throws IOException Error processing the Elf file.
* @throws IOException Error processing the Elf file. * @see Elf#Elf( String )
*/ */
public ElfHelper( Elf elf ) throws IOException { public ElfHelper(String filename) throws IOException {
this.elf = elf; elf = new Elf(filename);
commonSetup(); commonSetup();
} }
/** public ElfHelper(String filename, boolean filton) throws IOException {
* Create a new <code>ElfHelper</code> based on the given filename. elf = new Elf(filename, filton);
* commonSetup();
* @param filename The file to use for creating a new Elf object. }
* @throws IOException Error processing the Elf file.
* @see Elf#Elf( String ) /** Give back the Elf object that this helper is wrapping */
*/ public Elf getElf() {
public ElfHelper( String filename ) throws IOException { return elf;
elf = new Elf( filename ); }
commonSetup();
} public Elf.Symbol[] getExternalFunctions() throws IOException {
Vector v = new Vector();
public ElfHelper( String filename, boolean filton ) throws IOException {
elf = new Elf( filename, filton ); loadSymbols();
commonSetup(); loadSections();
}
for (int i = 0; i < dynsyms.length; i++) {
/** Give back the Elf object that this helper is wrapping */ if (dynsyms[i].st_bind() == Elf.Symbol.STB_GLOBAL && dynsyms[i].st_type() == Elf.Symbol.STT_FUNC) {
public Elf getElf() { int idx = dynsyms[i].st_shndx;
return elf; if (idx < 0)
} continue;
if (sections[idx].sh_type == Elf.Section.SHT_NULL)
public Elf.Symbol[] getExternalFunctions() v.add(dynsyms[i]);
throws IOException }
{ }
Vector v = new Vector();
Elf.Symbol[] ret = (Elf.Symbol[]) v.toArray(new Elf.Symbol[0]);
loadSymbols(); Arrays.sort(ret, new SymbolSortCompare());
loadSections(); return ret;
}
for( int i=0; i<dynsyms.length; i++ )
{ public Elf.Symbol[] getExternalObjects() throws IOException {
if( dynsyms[i].st_bind() == Elf.Symbol.STB_GLOBAL && Vector v = new Vector();
dynsyms[i].st_type() == Elf.Symbol.STT_FUNC )
{ loadSymbols();
int idx = dynsyms[i].st_shndx; loadSections();
if( idx < 0 )
continue; for (int i = 0; i < dynsyms.length; i++) {
if( sections[idx].sh_type == Elf.Section.SHT_NULL ) if (dynsyms[i].st_bind() == Elf.Symbol.STB_GLOBAL && dynsyms[i].st_type() == Elf.Symbol.STT_OBJECT) {
v.add( dynsyms[i] ); int idx = dynsyms[i].st_shndx;
} if (idx < 0)
} continue;
Elf.Symbol[] ret = (Elf.Symbol[])v.toArray( new Elf.Symbol[0] ); if (sections[idx].sh_type == Elf.Section.SHT_NULL)
Arrays.sort( ret, new SymbolSortCompare() ); v.add(dynsyms[i]);
return ret; }
} }
Elf.Symbol[] ret = (Elf.Symbol[]) v.toArray(new Elf.Symbol[0]);
public Elf.Symbol[] getExternalObjects() Arrays.sort(ret, new SymbolSortCompare());
throws IOException return ret;
{ }
Vector v = new Vector();
public Elf.Symbol[] getUndefined() throws IOException {
loadSymbols(); Vector v = new Vector();
loadSections();
loadSymbols();
for( int i=0; i<dynsyms.length; i++ )
{ for (int i = 0; i < dynsyms.length; i++) {
if( dynsyms[i].st_bind() == Elf.Symbol.STB_GLOBAL && if (dynsyms[i].st_shndx == Elf.Symbol.SHN_UNDEF)
dynsyms[i].st_type() == Elf.Symbol.STT_OBJECT ) v.add(dynsyms[i]);
{ }
int idx = dynsyms[i].st_shndx;
if( idx < 0 ) Elf.Symbol[] ret = (Elf.Symbol[]) v.toArray(new Elf.Symbol[0]);
continue; Arrays.sort(ret, new SymbolSortCompare());
return ret;
if( sections[idx].sh_type == Elf.Section.SHT_NULL ) }
v.add( dynsyms[i] );
} public Elf.Symbol[] getLocalFunctions() throws IOException {
} Vector v = new Vector();
Elf.Symbol[] ret = (Elf.Symbol[])v.toArray( new Elf.Symbol[0] ); loadSymbols();
Arrays.sort( ret, new SymbolSortCompare() ); loadSections();
return ret;
} for (int i = 0; i < symbols.length; i++) {
if (symbols[i].st_bind() == Elf.Symbol.STB_GLOBAL && symbols[i].st_type() == Elf.Symbol.STT_FUNC) {
int idx = symbols[i].st_shndx;
public Elf.Symbol[] getUndefined() if (idx < 0)
throws IOException continue;
{
Vector v = new Vector(); if (sections[idx].sh_type != Elf.Section.SHT_NULL)
v.add(symbols[i]);
loadSymbols(); }
}
for( int i=0; i<dynsyms.length; i++ )
{ Elf.Symbol[] ret = (Elf.Symbol[]) v.toArray(new Elf.Symbol[0]);
if( dynsyms[i].st_shndx == Elf.Symbol.SHN_UNDEF ) Arrays.sort(ret, new SymbolSortCompare());
v.add( dynsyms[i] ); return ret;
} }
Elf.Symbol[] ret = (Elf.Symbol[])v.toArray( new Elf.Symbol[0] ); public Elf.Symbol[] getLocalObjects() throws IOException {
Arrays.sort( ret, new SymbolSortCompare() ); Vector v = new Vector();
return ret;
} loadSymbols();
loadSections();
for (int i = 0; i < symbols.length; i++) {
public Elf.Symbol[] getLocalFunctions() if (symbols[i].st_bind() == Elf.Symbol.STB_GLOBAL && symbols[i].st_type() == Elf.Symbol.STT_OBJECT) {
throws IOException int idx = symbols[i].st_shndx;
{ if (idx < 0)
Vector v = new Vector(); continue;
loadSymbols(); if (sections[idx].sh_type != Elf.Section.SHT_NULL)
loadSections(); v.add(symbols[i]);
}
for( int i=0; i<symbols.length; i++ ) }
{
if( symbols[i].st_bind() == Elf.Symbol.STB_GLOBAL && Elf.Symbol[] ret = (Elf.Symbol[]) v.toArray(new Elf.Symbol[0]);
symbols[i].st_type() == Elf.Symbol.STT_FUNC ) Arrays.sort(ret, new SymbolSortCompare());
{ return ret;
int idx = symbols[i].st_shndx; }
if( idx < 0 )
continue; public Elf.Symbol[] getCommonObjects() throws IOException {
Vector v = new Vector();
if( sections[idx].sh_type != Elf.Section.SHT_NULL )
v.add( symbols[i] ); loadSymbols();
} loadSections();
}
for (int i = 0; i < symbols.length; i++) {
Elf.Symbol[] ret = (Elf.Symbol[])v.toArray( new Elf.Symbol[0] ); if (symbols[i].st_bind() == Elf.Symbol.STB_GLOBAL && symbols[i].st_type() == Elf.Symbol.STT_OBJECT) {
Arrays.sort( ret, new SymbolSortCompare() ); int idx = symbols[i].st_shndx;
return ret; if (idx == Elf.Symbol.SHN_COMMON) {
} v.add(symbols[i]);
}
}
public Elf.Symbol[] getLocalObjects() }
throws IOException
{ Elf.Symbol[] ret = (Elf.Symbol[]) v.toArray(new Elf.Symbol[0]);
Vector v = new Vector(); Arrays.sort(ret, new SymbolSortCompare());
return ret;
loadSymbols(); }
loadSections();
public Elf.Dynamic[] getNeeded() throws IOException {
for( int i=0; i<symbols.length; i++ ) Vector v = new Vector();
{
if( symbols[i].st_bind() == Elf.Symbol.STB_GLOBAL && loadDynamics();
symbols[i].st_type() == Elf.Symbol.STT_OBJECT )
{ for (int i = 0; i < dynamics.length; i++) {
int idx = symbols[i].st_shndx; if (dynamics[i].d_tag == Elf.Dynamic.DT_NEEDED)
if( idx < 0 ) v.add(dynamics[i]);
continue; }
return (Elf.Dynamic[]) v.toArray(new Elf.Dynamic[0]);
if( sections[idx].sh_type != Elf.Section.SHT_NULL ) }
v.add( symbols[i] );
} public String getSoname() throws IOException {
} String soname = "";
Elf.Symbol[] ret = (Elf.Symbol[])v.toArray( new Elf.Symbol[0] ); loadDynamics();
Arrays.sort( ret, new SymbolSortCompare() );
return ret; for (int i = 0; i < dynamics.length; i++) {
} if (dynamics[i].d_tag == Elf.Dynamic.DT_SONAME)
soname = dynamics[i].toString();
}
return soname;
public Elf.Symbol[] getCommonObjects() throws IOException }
{
Vector v = new Vector(); private String getSubUsage(String full, String name) {
int start, end;
loadSymbols(); //boolean has_names = false;
loadSections(); //boolean has_languages = false;
start = 0;
for( int i=0; i<symbols.length; i++ ) end = 0;
{
if( symbols[i].st_bind() == Elf.Symbol.STB_GLOBAL && for (int i = 0; i < full.length(); i++) {
symbols[i].st_type() == Elf.Symbol.STT_OBJECT ) if (full.charAt(i) == '%') {
{ if (full.charAt(i + 1) == '-') {
int idx = symbols[i].st_shndx; if (start == 0) {
if( idx == Elf.Symbol.SHN_COMMON ) int eol = full.indexOf('\n', i + 2);
{ String temp = full.substring(i + 2, eol);
v.add( symbols[i] ); if (temp.compareTo(name) == 0)
} start = eol;
}
} //has_names = true;
} else if (end == 0) {
Elf.Symbol[] ret = (Elf.Symbol[])v.toArray( new Elf.Symbol[0] ); end = i - 1;
Arrays.sort( ret, new SymbolSortCompare() ); }
return ret; }
}
//if( full.charAt( i+1 ) == '=' )
//has_languages = true;
}
public Elf.Dynamic[] getNeeded() }
throws IOException
{ if (end == 0)
Vector v = new Vector(); end = full.length();
loadDynamics(); if (start == 0)
return full;
for( int i=0; i<dynamics.length; i++ )
{ return full.substring(start, end);
if( dynamics[i].d_tag == Elf.Dynamic.DT_NEEDED ) }
v.add( dynamics[i] );
} public String getQnxUsage() throws IOException {
return( Elf.Dynamic[])v.toArray( new Elf.Dynamic[0] );
} loadSections();
for (int i = 0; i < sections.length; i++) {
public String getSoname() throws IOException { if (sections[i].toString().compareTo("QNX_usage") == 0) {
String soname = ""; File file = new File(elf.getFilename());
loadDynamics(); String full_usage = new String(sections[i].loadSectionData());
String usage = getSubUsage(full_usage, file.getName());
for( int i=0; i<dynamics.length; i++ ) StringBuffer buffer = new StringBuffer(usage);
{
if( dynamics[i].d_tag == Elf.Dynamic.DT_SONAME ) for (int j = 0; j < buffer.length(); j++) {
soname = dynamics[i].toString(); if (buffer.charAt(j) == '%') {
} if (buffer.charAt(j + 1) == 'C')
return soname; buffer.replace(j, j + 2, file.getName());
} }
}
private String getSubUsage( String full, String name ) { return buffer.toString();
int start, end; }
//boolean has_names = false; }
//boolean has_languages = false; return new String("");
start = 0; }
end = 0;
public Sizes getSizes() throws IOException {
for( int i=0; i<full.length(); i++ ) long text, data, bss;
{
if( full.charAt( i ) == '%' ) text = 0;
{ data = 0;
if( full.charAt( i+1 ) == '-' ) bss = 0;
{
if( start == 0 ) loadSections();
{
int eol = full.indexOf( '\n', i+2 ); for (int i = 0; i < sections.length; i++) {
String temp = full.substring( i+2, eol ); if (sections[i].sh_type != Elf.Section.SHT_NOBITS) {
if( temp.compareTo( name ) == 0 ) if (sections[i].sh_flags == (Elf.Section.SHF_WRITE | Elf.Section.SHF_ALLOC)) {
start = eol; data += sections[i].sh_size;
} else if ((sections[i].sh_flags & Elf.Section.SHF_ALLOC) != 0) {
//has_names = true; text += sections[i].sh_size;
} }
else if( end == 0 ) } else {
{ if (sections[i].sh_flags == (Elf.Section.SHF_WRITE | Elf.Section.SHF_ALLOC)) {
end = i - 1; bss += sections[i].sh_size;
} }
} }
}
//if( full.charAt( i+1 ) == '=' )
//has_languages = true; return new Sizes(text, data, bss);
} }
}
if( end == 0 )
end = full.length();
if( start == 0 )
return full;
return full.substring( start, end );
}
public String getQnxUsage() throws IOException {
loadSections();
for( int i=0; i<sections.length; i++ )
{
if( sections[i].toString().compareTo( "QNX_usage" ) == 0 )
{
File file = new File( elf.getFilename() );
String full_usage = new String( sections[i].loadSectionData() );
String usage = getSubUsage( full_usage, file.getName() );
StringBuffer buffer = new StringBuffer( usage );
for( int j=0; j<buffer.length(); j++ )
{
if( buffer.charAt( j ) == '%' )
{
if( buffer.charAt( j+1 ) == 'C' )
buffer.replace( j, j+2, file.getName() );
}
}
return buffer.toString();
}
}
return new String( "" );
}
public Sizes getSizes() throws IOException {
long text, data, bss;
text = 0;
data = 0;
bss = 0;
loadSections();
for( int i=0; i<sections.length; i++ )
{
if( sections[i].sh_type != Elf.Section.SHT_NOBITS )
{
if( sections[i].sh_flags ==
( Elf.Section.SHF_WRITE | Elf.Section.SHF_ALLOC ) )
{
data += sections[i].sh_size;
}
else if( ( sections[i].sh_flags & Elf.Section.SHF_ALLOC ) != 0 )
{
text += sections[i].sh_size;
}
}
else
{
if( sections[i].sh_flags ==
( Elf.Section.SHF_WRITE | Elf.Section.SHF_ALLOC ) )
{
bss += sections[i].sh_size;
}
}
}
return new Sizes( text, data, bss );
}
} }