From 8ab6e1bb4ccf0b14a0ecb1e9d0c9ee6969761f10 Mon Sep 17 00:00:00 2001 From: David Inglis Date: Wed, 28 May 2003 12:59:08 +0000 Subject: [PATCH] fixed bug with mips dyn section reading new method cleanup --- core/org.eclipse.cdt.core/ChangeLog | 9 + .../utils/org/eclipse/cdt/utils/elf/Elf.java | 33 +- .../org/eclipse/cdt/utils/elf/ElfHelper.java | 737 ++++++++---------- 3 files changed, 360 insertions(+), 419 deletions(-) diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 260266d3417..082bd69d897 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -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): 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 31cc77f959c..d3a4d97f28a 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 @@ -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 ) diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ElfHelper.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ElfHelper.java index 8a239f732e9..c10ac1157bc 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ElfHelper.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/ElfHelper.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.Vector; - /** * ElfHelper is a wrapper class for the Elf 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; iElfHelper using an existing Elf - * 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 ElfHelper 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; iElfHelper using an existing Elf + * 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 ElfHelper 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); + } } - -