1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 06:45:43 +02:00

Bug 337254 - Binary not found - Universal ppc+i386 executables are not picked up on 64 bit machines. Patch by Johan van den Berg.

This commit is contained in:
Sergey Prigogin 2011-02-16 01:30:34 +00:00
parent 98559b4f80
commit 97e5359102

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2009 QNX Software Systems and others.
* Copyright (c) 2000, 2011 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -50,9 +50,7 @@ public class MachO64 {
protected static final SymbolComparator symbol_comparator = new SymbolComparator();
public class MachOhdr {
/* values of magic */
public final static int MH_MAGIC = 0xfeedface; /* the mach magic number */
public final static int MH_CIGAM = 0xcefaedfe;
@ -204,45 +202,42 @@ public class MachO64 {
public int sizeofcmds; /* the size of all the load commands */
public int flags; /* flags */
public int reserved; // 64bit reserved
protected MachOhdr() throws IOException {
efile.seek(0);
efile.setEndian(false);
magic = efile.readIntE();
if ( magic == MH_CIGAM || magic == MH_CIGAM_64) {
if (magic == MH_CIGAM || magic == MH_CIGAM_64) {
efile.setEndian(true);
if (MH_CIGAM_64 == magic)
b64 = true;
}
else
if ( magic == MH_UNIVERSAL)
{
} else if (magic == MH_UNIVERSAL) {
String arch = System.getProperty("os.arch"); //$NON-NLS-1$
int numArchives = efile.readIntE();
while (numArchives-- > 0)
{
while (numArchives-- > 0) {
int cpuType = efile.readIntE(); // cpuType
efile.readIntE(); // cpuSubType
int archiveOffset = efile.readIntE(); // archiveOffset
efile.readIntE(); // archiveSize
efile.readIntE(); // archiveAlignment
if ((cpuType == MachO64.MachOhdr.CPU_TYPE_I386 && arch.equalsIgnoreCase("i386")) || //$NON-NLS-1$
if ((cpuType == MachO64.MachOhdr.CPU_TYPE_I386 &&
(arch.equalsIgnoreCase("i386") || arch.equalsIgnoreCase("x86_64"))) || //$NON-NLS-1$ //$NON-NLS-2$
(cpuType == MachO64.MachOhdr.CPU_TYPE_POWERPC && arch.equalsIgnoreCase("ppc")) || //$NON-NLS-1$
(cpuType == MachO64.MachOhdr.CPU_TYPE_X86_64 && arch.equalsIgnoreCase("x86_64"))) //$NON-NLS-1$
{
(cpuType == MachO64.MachOhdr.CPU_TYPE_X86_64 && arch.equalsIgnoreCase("x86_64"))) { //$NON-NLS-1$
if (cpuType == MachO64.MachOhdr.CPU_TYPE_X86_64)
b64 = true;
efile.seek(archiveOffset);
magic = efile.readIntE();
if ( magic == MH_CIGAM || magic == MH_CIGAM_64)
if (magic == MH_CIGAM || magic == MH_CIGAM_64)
efile.setEndian(true);
else if ( magic != MH_MAGIC && magic != MH_MAGIC_64)
else if (magic != MH_MAGIC && magic != MH_MAGIC_64)
throw new IOException(CCorePlugin.getResourceString("Util.exception.notMACHO")); //$NON-NLS-1$
break;
}
}
}
else if ( magic != MH_MAGIC && magic != MH_MAGIC_64)
} else if (magic != MH_MAGIC && magic != MH_MAGIC_64) {
throw new IOException(CCorePlugin.getResourceString("Util.exception.notMACHO")); //$NON-NLS-1$
}
if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64)
b64 = true;
cputype = efile.readIntE();
@ -260,41 +255,37 @@ public class MachO64 {
boolean isle = false;
int offset = 0;
magic = makeInt(bytes, offset, isle); offset += 4;
if ( magic == MH_CIGAM || magic == MH_CIGAM_64) {
if (magic == MH_CIGAM || magic == MH_CIGAM_64) {
isle = true;
if (MH_CIGAM_64 == magic)
b64 = true;
}
else
if ( magic == MH_UNIVERSAL)
{
} else if (magic == MH_UNIVERSAL) {
String arch = System.getProperty("os.arch"); //$NON-NLS-1$
int numArchives = makeInt(bytes, offset, isle); offset += 4;
while (numArchives-- > 0)
{
while (numArchives-- > 0) {
int cpuType = makeInt(bytes, offset, isle); offset += 4;
offset += 4; // cpuSubType
int archiveOffset = makeInt(bytes, offset, isle); offset += 4;
offset += 4; // archiveSize
offset += 4; // archiveAlignment
if ((cpuType == MachO64.MachOhdr.CPU_TYPE_I386 && arch.equalsIgnoreCase("i386")) || //$NON-NLS-1$
if ((cpuType == MachO64.MachOhdr.CPU_TYPE_I386 &&
(arch.equalsIgnoreCase("i386") || arch.equalsIgnoreCase("x86_64"))) || //$NON-NLS-1$ //$NON-NLS-2$
(cpuType == MachO64.MachOhdr.CPU_TYPE_POWERPC && arch.equalsIgnoreCase("ppc")) || //$NON-NLS-1$
(cpuType == MachO64.MachOhdr.CPU_TYPE_X86_64 && arch.equalsIgnoreCase("x86_64"))) //$NON-NLS-1$
{
(cpuType == MachO64.MachOhdr.CPU_TYPE_X86_64 && arch.equalsIgnoreCase("x86_64"))) { //$NON-NLS-1$
if (cpuType == MachO64.MachOhdr.CPU_TYPE_X86_64)
b64 = true;
offset = archiveOffset;
magic = makeInt(bytes, offset, isle); offset += 4;
if ( magic == MH_CIGAM || magic == MH_CIGAM_64 )
if (magic == MH_CIGAM || magic == MH_CIGAM_64 )
isle = true;
else if ( magic != MH_MAGIC && magic != MH_MAGIC_64)
else if (magic != MH_MAGIC && magic != MH_MAGIC_64)
throw new IOException(CCorePlugin.getResourceString("Util.exception.notMACHO")); //$NON-NLS-1$
break;
}
}
}
else if ( magic != MH_MAGIC && magic != MH_MAGIC_64)
} else if (magic != MH_MAGIC && magic != MH_MAGIC_64) {
throw new IOException(CCorePlugin.getResourceString("Util.exception.notMACHO")); //$NON-NLS-1$
}
if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64)
b64 = true;
cputype = makeInt(bytes, offset, isle); offset += 4;
@ -307,16 +298,16 @@ public class MachO64 {
reserved = makeInt(bytes, offset, isle); offset += 4;
}
}
public boolean is64() {
return b64;
}
}
private static final int makeInt(byte [] val, int offset, boolean isle) throws IOException
{
private static final int makeInt(byte [] val, int offset, boolean isle) throws IOException {
if (val.length < offset + 4)
throw new IOException();
if ( isle ) {
if (isle ) {
return (((val[offset + 3] & 0xff) << 24) |
((val[offset + 2] & 0xff) << 16) |
((val[offset + 1] & 0xff) << 8) |
@ -410,7 +401,6 @@ public class MachO64 {
}
public class Section {
public final static int SECTION_TYP = 0x000000ff; /* 256 section types */
public final static int SECTION_ATTRIBUTES = 0xffffff00; /* 24 section attributes */
public final static int SECTION_ATTRIBUTES_USR =0xff000000; /* User setable attributes */
@ -463,7 +453,7 @@ public class MachO64 {
@Override
public String toString() {
if ( lc_str_name == null ) {
if (lc_str_name == null ) {
return EMPTY_STRING;
}
return lc_str_name;
@ -485,7 +475,7 @@ public class MachO64 {
@Override
public String toString() {
if ( lc_str_name == null ) {
if (lc_str_name == null ) {
return EMPTY_STRING;
}
return lc_str_name;
@ -502,7 +492,7 @@ public class MachO64 {
@Override
public String toString() {
if ( lc_str_name == null ) {
if (lc_str_name == null ) {
return EMPTY_STRING;
}
return lc_str_name;
@ -515,7 +505,7 @@ public class MachO64 {
@Override
public String toString() {
if ( lc_str_name == null ) {
if (lc_str_name == null ) {
return EMPTY_STRING;
}
return lc_str_name;
@ -528,7 +518,7 @@ public class MachO64 {
@Override
public String toString() {
if ( lc_str_name == null ) {
if (lc_str_name == null ) {
return EMPTY_STRING;
}
return lc_str_name;
@ -541,7 +531,7 @@ public class MachO64 {
@Override
public String toString() {
if ( lc_str_name == null ) {
if (lc_str_name == null ) {
return EMPTY_STRING;
}
return lc_str_name;
@ -556,7 +546,7 @@ public class MachO64 {
@Override
public String toString() {
if ( lc_str_name == null ) {
if (lc_str_name == null ) {
return EMPTY_STRING;
}
return lc_str_name;
@ -569,7 +559,7 @@ public class MachO64 {
@Override
public String toString() {
if ( lc_str_name == null ) {
if (lc_str_name == null ) {
return EMPTY_STRING;
}
return lc_str_name;
@ -676,32 +666,30 @@ public class MachO64 {
@Override
public String toString() {
if ( lc_str_name == null ) {
if (lc_str_name == null ) {
return EMPTY_STRING;
}
return lc_str_name;
}
}
private void commonSetup( String file, long offset, boolean filton )
throws IOException
{
private void commonSetup(String file, long offset, boolean filton ) throws IOException {
this.cppFiltEnabled = filton;
try {
efile = new ERandomAccessFile(file, "r"); //$NON-NLS-1$
efile.setFileOffset( offset );
efile.setFileOffset(offset );
mhdr = new MachOhdr();
this.file = file;
} finally {
if ( mhdr == null ) {
if (mhdr == null ) {
dispose();
}
}
}
protected String string_from_macho_symtab(MachO64.SymtabCommand symtab, int index) throws IOException {
if ( index > symtab.strsize ) {
if (index > symtab.strsize ) {
return EMPTY_STRING;
}
efile.seek(symtab.stroff + index);
@ -808,11 +796,11 @@ public class MachO64 {
public int compareTo(Object obj) {
long thisVal = 0;
long anotherVal = 0;
if ( obj instanceof Symbol ) {
if (obj instanceof Symbol ) {
Symbol sym = (Symbol)obj;
thisVal = this.n_value;
anotherVal = sym.n_value;
} else if ( obj instanceof Long ) {
} else if (obj instanceof Long ) {
Long val = (Long)obj;
anotherVal = val.longValue();
thisVal = this.n_value;
@ -825,7 +813,7 @@ public class MachO64 {
if (n_strx == 0 || symtab == null) {
return EMPTY_STRING;
}
if ( name == null ) {
if (name == null ) {
try {
name = cppFilt(string_from_macho_symtab(symtab, (int)n_strx));
} catch (IOException e ) {
@ -905,7 +893,7 @@ public class MachO64 {
* then -1 is returned.
*/
public int getFuncLineNumber() {
if ( line == null ) {
if (line == null ) {
lineInfo();
}
if (line == null) {
@ -933,9 +921,9 @@ public class MachO64 {
}
int ndx = Arrays.binarySearch(lines, new Long(value));
if ( ndx >= 0 )
if (ndx >= 0 )
return lines[ndx];
if ( ndx == -1 ) {
if (ndx == -1 ) {
return null;
}
ndx = -ndx - 1;
@ -948,7 +936,7 @@ public class MachO64 {
}
/**
* We have to implement a separate compararator since when we do the
* We have to implement a separate comparator since when we do the
* binary search down below we are using a Long and a Symbol object
* and the Long doesn't know how to compare against a Symbol so if
* we compare Symbol vs Long it is ok, but not if we do Long vs Symbol.
@ -956,24 +944,22 @@ public class MachO64 {
public static class SymbolComparator implements Comparator<Object> {
long val1, val2;
public int compare(Object o1, Object o2) {
if(o1 instanceof Long) {
val1 = ((Long)o1).longValue();
} else if(o1 instanceof Symbol) {
val1 = ((Symbol)o1).n_value;
if (o1 instanceof Long) {
val1 = ((Long) o1).longValue();
} else if (o1 instanceof Symbol) {
val1 = ((Symbol) o1).n_value;
} else {
return -1;
}
if(o2 instanceof Long) {
val2 = ((Long)o2).longValue();
} else if(o2 instanceof Symbol) {
val2 = ((Symbol)o2).n_value;
if (o2 instanceof Long) {
val2 = ((Long) o2).longValue();
} else if (o2 instanceof Symbol) {
val2 = ((Symbol) o2).n_value;
} else {
return -1;
}
return (val1 == val2) ? 0
: ((val1 < val2) ? -1 : 1);
return val1 == val2 ? 0 : val1 < val2 ? -1 : 1;
}
}
@ -989,11 +975,11 @@ public class MachO64 {
public int compareTo(Object obj) {
long thisVal = 0;
long anotherVal = 0;
if ( obj instanceof Line ) {
if (obj instanceof Line ) {
Line l = (Line)obj;
thisVal = this.address;
anotherVal = l.address;
} else if ( obj instanceof Long ) {
} else if (obj instanceof Long ) {
Long val = (Long)obj;
anotherVal = val.longValue();
thisVal = this.address;
@ -1013,26 +999,26 @@ public class MachO64 {
}
public MachO64 (String file, long offset) throws IOException {
commonSetup( file, offset, true );
commonSetup(file, offset, true );
}
public MachO64 (String file) throws IOException {
commonSetup( file, 0, true );
commonSetup(file, 0, true );
}
public MachO64 (String file, long offset, boolean filton) throws IOException {
commonSetup( file, offset, filton );
commonSetup(file, offset, filton );
}
public MachO64 (String file, boolean filton) throws IOException {
commonSetup( file, 0, filton );
commonSetup(file, 0, filton );
}
public boolean cppFilterEnabled() {
return cppFiltEnabled;
}
public void setCppFilter( boolean enabled ) {
public void setCppFilter(boolean enabled ) {
cppFiltEnabled = enabled;
}
@ -1080,7 +1066,7 @@ public class MachO64 {
public Attribute getAttributes() throws IOException {
Attribute attrib = new Attribute();
switch( mhdr.filetype ) {
switch(mhdr.filetype ) {
case MachO64.MachOhdr.MH_OBJECT:
attrib.type = Attribute.MACHO_TYPE_OBJ;
break;
@ -1103,25 +1089,25 @@ public class MachO64 {
case MachO64.MachOhdr.CPU_TYPE_X86_64:
attrib.cpu = "x86_64"; //$NON-NLS-1$
break;
case MachO64.MachOhdr.CPU_TYPE_I386 :
case MachO64.MachOhdr.CPU_TYPE_I386:
attrib.cpu = "x86"; //$NON-NLS-1$
break;
case MachO64.MachOhdr.CPU_TYPE_POWERPC :
case MachO64.MachOhdr.CPU_TYPE_POWERPC:
attrib.cpu = "ppc"; //$NON-NLS-1$
break;
case MachO64.MachOhdr.CPU_TYPE_VAX :
case MachO64.MachOhdr.CPU_TYPE_VAX:
attrib.cpu = "vax"; //$NON-NLS-1$
break;
case MachO64.MachOhdr.CPU_TYPE_MC680x0 :
case MachO64.MachOhdr.CPU_TYPE_MC680x0:
attrib.cpu = "m68k"; //$NON-NLS-1$
break;
case MachO64.MachOhdr.CPU_TYPE_MC98000 :
case MachO64.MachOhdr.CPU_TYPE_MC98000:
attrib.cpu = "98000"; //$NON-NLS-1$
break;
case MachO64.MachOhdr.CPU_TYPE_MC88000 :
case MachO64.MachOhdr.CPU_TYPE_MC88000:
attrib.cpu = "88000"; //$NON-NLS-1$
break;
case MachO64.MachOhdr.CPU_TYPE_HPPA :
case MachO64.MachOhdr.CPU_TYPE_HPPA:
attrib.cpu = "hp"; //$NON-NLS-1$
break;
case MachO64.MachOhdr.CPU_TYPE_SPARC:
@ -1137,11 +1123,11 @@ public class MachO64 {
switch (mhdr.magic) {
case MachO64.MachOhdr.MH_CIGAM_64:
case MachO64.MachOhdr.MH_CIGAM :
case MachO64.MachOhdr.MH_CIGAM:
attrib.isle = true;
break;
case MachO64.MachOhdr.MH_MAGIC_64 :
case MachO64.MachOhdr.MH_MAGIC :
case MachO64.MachOhdr.MH_MAGIC_64:
case MachO64.MachOhdr.MH_MAGIC:
attrib.isle = false;
break;
}
@ -1161,7 +1147,6 @@ public class MachO64 {
}
public static Attribute getAttributes(byte [] array) throws IOException {
MachO64 emptyMachO = new MachO64();
emptyMachO.mhdr = emptyMachO.new MachOhdr(array);
//emptyMachO.sections = new MachO64.Section[0];
@ -1307,15 +1292,14 @@ public class MachO64 {
}
}
}
}
private ArrayList<Section> getSections(SegmentCommand seg) throws IOException {
if ( seg.nsects == 0 ) {
if (seg.nsects == 0 ) {
return new ArrayList<Section>();
}
ArrayList<Section> sections = new ArrayList<Section>();
for ( int i = 0; i < seg.nsects; i++ ) {
for (int i = 0; i < seg.nsects; i++ ) {
Section section = new Section();
byte[] sectname = new byte[16];
byte[] segname = new byte[16];
@ -1327,7 +1311,7 @@ public class MachO64 {
if (b64) {
section.addr = efile.readLongE();
section.size = efile.readLongE();
}else {
} else {
section.addr = efile.readIntE();
section.size = efile.readIntE();
}
@ -1346,11 +1330,11 @@ public class MachO64 {
}
// private TwoLevelHint[] getTwoLevelHints(int nhints) throws IOException {
// if ( nhints == 0 ) {
// if (nhints == 0 ) {
// return new TwoLevelHint[0];
// }
// TwoLevelHint[] tlhints = new TwoLevelHint[nhints];
// for ( int i = 0; i < nhints; i++ ) {
// for (int i = 0; i < nhints; i++ ) {
// int field = efile.readIntE();
// tlhints[i] = new TwoLevelHint();
// tlhints[i].isub_image = (field & 0xff000000) >> 24;
@ -1361,7 +1345,7 @@ public class MachO64 {
private String getCStr() throws IOException {
StringBuffer str = new StringBuffer();
while( true ) {
while(true ) {
byte tmp = efile.readByte();
if (tmp == 0)
break;
@ -1384,13 +1368,13 @@ public class MachO64 {
}
private void loadLoadCommands() throws IOException {
if ( loadcommands == null ) {
if ( mhdr.ncmds == 0 ) {
if (loadcommands == null ) {
if (mhdr.ncmds == 0 ) {
loadcommands = new LoadCommand[0];
return;
}
loadcommands = new LoadCommand[mhdr.ncmds];
for ( int i = 0; i < mhdr.ncmds; i++ ) {
for (int i = 0; i < mhdr.ncmds; i++ ) {
int cmd = efile.readIntE();
int len = efile.readIntE();
@ -1684,7 +1668,7 @@ public class MachO64 {
}
public void loadBinary() throws IOException {
if ( loadcommands == null ) {
if (loadcommands == null ) {
loadLoadCommands();
loadSymbolTable();
loadLineTable();
@ -1735,23 +1719,23 @@ public class MachO64 {
}
/* return the address of the function that address is in */
public Symbol getSymbol( long vma ) {
if ( symbols == null ) {
public Symbol getSymbol(long vma ) {
if (symbols == null ) {
return null;
}
int ndx = Arrays.binarySearch(symbols, new Long(vma), symbol_comparator);
if ( ndx > 0 )
if (ndx > 0 )
return symbols[ndx];
if ( ndx == -1 ) {
if (ndx == -1 ) {
return null;
}
ndx = -ndx - 1;
return symbols[ndx-1];
}
public long swapInt( long val ) {
if ( mhdr.magic == MachOhdr.MH_CIGAM || mhdr.magic == MachOhdr.MH_CIGAM_64 ) {
public long swapInt(long val ) {
if (mhdr.magic == MachOhdr.MH_CIGAM || mhdr.magic == MachOhdr.MH_CIGAM_64 ) {
short tmp[] = new short[4];
tmp[0] = (short)(val & 0x00ff);
tmp[1] = (short)((val >> 8) & 0x00ff);
@ -1762,8 +1746,8 @@ public class MachO64 {
return val;
}
public int swapShort( short val ) {
if ( mhdr.magic == MachOhdr.MH_CIGAM || mhdr.magic == MachOhdr.MH_CIGAM_64) {
public int swapShort(short val ) {
if (mhdr.magic == MachOhdr.MH_CIGAM || mhdr.magic == MachOhdr.MH_CIGAM_64) {
short tmp[] = new short[2];
tmp[0] = (short)(val & 0x00ff);
tmp[1] = (short)((val >> 8) & 0x00ff);
@ -1780,18 +1764,18 @@ public class MachO64 {
ISymbolReader symReader = null;
try {
if ( loadcommands == null ) {
if (loadcommands == null ) {
loadLoadCommands();
}
} catch (Throwable e) { e.printStackTrace(); }
} catch (Throwable e) {
e.printStackTrace();
}
for (LoadCommand loadcommand : loadcommands) {
if (loadcommand.cmd == LoadCommand.LC_SYMTAB)
{
if (loadcommand.cmd == LoadCommand.LC_SYMTAB) {
symtab = (SymtabCommand)loadcommand;
try {
int symSize = symtab.nsyms * (mhdr.is64() ? StabConstant.SIZE_64 :StabConstant.SIZE);
int symSize = symtab.nsyms * (mhdr.is64() ? StabConstant.SIZE_64 : StabConstant.SIZE);
byte[] data = new byte[symSize];
efile.seek(symtab.symoff);
efile.readFully(data);
@ -1799,8 +1783,9 @@ public class MachO64 {
efile.seek(symtab.stroff);
efile.readFully(stabstr);
symReader = new StabsReader(data, stabstr, getAttributes().isLittleEndian(),mhdr.is64());
} catch (Throwable e) { e.printStackTrace(); }
} catch (Throwable e) {
e.printStackTrace();
}
}
}
return symReader;