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
* 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_DYNSYM = 11;
public final static int SHT_LOPROC = 0x70000000;
/* sh_flags */
public final static int SHF_WRITE = 1;
public final static int SHF_ALLOC = 2;
@ -173,7 +175,7 @@ public class Elf {
efile.read(section_strtab);
}
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;
}
while( section_strtab[(int)sh_name + str_size] != 0)
@ -483,6 +485,8 @@ public class Elf {
}
public class Dynamic {
public final static int DYN_ENT_SIZE = 8;
public final static int DT_NULL = 0;
public final static int DT_NEEDED = 1;
public final static int DT_PLTRELSZ = 2;
@ -501,7 +505,6 @@ public class Elf {
public final static int DT_RPATH = 15;
public long d_tag;
public long d_val;
private Section section;
private String name;
@ -538,16 +541,15 @@ public class Elf {
}
ArrayList dynList = new ArrayList();
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());
if ( dynEnt.d_tag == Dynamic.DT_NULL )
break;
dynList.add(dynEnt);
} else {
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);
}
off+= Dynamic.DYN_ENT_SIZE;
}
return (Dynamic[])dynList.toArray(new Dynamic[0]);
}
@ -726,6 +728,17 @@ public class Elf {
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 {
if ( sections == null )

View file

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