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

2004-07-16 Vladimir Hirsl

1. Implementation of HP-UX SOM binary parser.

	* utils/org/eclipse/cdt/utils/som/AR.java
	* utils/org/eclipse/cdt/utils/som/SOM.java

	* utils/org/eclipse/cdt/utils/som/parser/ARMember.java
	* utils/org/eclipse/cdt/utils/som/parser/BinaryArchive.java
	* utils/org/eclipse/cdt/utils/som/parser/SOMParser.java
	* utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java
	* utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java

	2. Fixed a slight ommision in XXXBinaryObject classes

	* utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java
	* utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java
	* utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java
This commit is contained in:
Alain Magloire 2004-07-16 18:03:28 +00:00
parent 9766cb70c6
commit 224f6eb03a
16 changed files with 1746 additions and 7 deletions

View file

@ -1,3 +1,21 @@
2004-07-16 Vladimir Hirsl
1. Implementation of HP-UX SOM binary parser.
* utils/org/eclipse/cdt/utils/som/AR.java
* utils/org/eclipse/cdt/utils/som/SOM.java
* utils/org/eclipse/cdt/utils/som/parser/ARMember.java
* utils/org/eclipse/cdt/utils/som/parser/BinaryArchive.java
* utils/org/eclipse/cdt/utils/som/parser/SOMParser.java
* utils/org/eclipse/cdt/utils/som/parser/SOMBinaryObject.java
* utils/org/eclipse/cdt/utils/som/parser/SomSymbol.java
2. Fixed a slight ommision in XXXBinaryObject classes
* utils/org/eclipse/cdt/utils/coff/parser/CygwinPEBinaryObject.java
* utils/org/eclipse/cdt/utils/elf/parser/GNUElfBinaryObject.java
* utils/org/eclipse/cdt/utils/xcoff/parser/XCOFFBinaryObject.java
2004-07-15 Alain Magloire
Check for Empty path in the binary and copy the []IPathEntry

View file

@ -31,6 +31,7 @@ PEWindowsParser.name=PE Windows Parser
CygwinPEParser.name=Cygwin PE Parser
XCOFF32Parser.name=AIX XCOFF32 Parser
MachOParser.name=Mach-O Parser
SOMParser.name=HP-UX SOM Parser
CDTGNUCErrorParser.name=CDT GNU C/C++ Error Parser
CDTGNUAssemblerErrorParser.name=CDT GNU Assembler Error Parser

View file

@ -107,6 +107,16 @@
</run>
</cextension>
</extension>
<extension
id="SOM"
name="%SOMParser.name"
point="org.eclipse.cdt.core.BinaryParser">
<cextension>
<run
class="org.eclipse.cdt.utils.som.parser.SOMParser">
</run>
</cextension>
</extension>
<!-- This is for backward compatibility: an Typo was introduce in on of the realease
and "ELF" instead of "Elf" -->
<extension

View file

@ -176,6 +176,8 @@ public class CygwinPEBinaryObject extends PEBinaryObject {
list.add(new CygwinSymbol(this, name, type, addr, size, file, startLine, endLine));
} catch (IOException e) {
addr2line = null;
// the symbol still needs to be added
list.add(new CygwinSymbol(this, name, type, addr, size));
}
} else {
list.add(new CygwinSymbol(this, name, type, addr, size));

View file

@ -136,6 +136,9 @@ public class GNUElfBinaryObject extends ElfBinaryObject {
int endLine = addr2line.getLineNumber(addr + size - 1);
list.add(new GNUSymbol(this, name, type, addr, size, file, startLine, endLine));
} catch (IOException e) {
addr2line = null;
// the symbol still needs to be added
list.add(new GNUSymbol(this, name, type, addr, size));
}
} else {
list.add(new GNUSymbol(this, name, type, addr, size));

View file

@ -0,0 +1,352 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.utils.som;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Vector;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.utils.coff.ReadMemoryAccess;
/**
* The <code>AR</code> class is used for parsing standard SOM archive (ar) files.
*
* @author vhirsl
*/
public class AR {
public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
protected String filename;
protected RandomAccessFile file;
private byte[] ar_magic = new byte[8];
private LSTHeader lstHeader;
private ARHeader[] memberHeaders;
/**
* Archive and archive member header. Does not include 8-byte magic character.
*
* @author vhirsl
*/
public class ARHeader {
public static final int HEADER_SIZE = 60;
// fields
private byte[] ar_name = new byte[16]; // file member name - '/' terminated
private byte[] ar_date = new byte[12]; // file member date - decimal
private byte[] ar_uid = new byte[6]; // file member user id - decimal
private byte[] ar_gid = new byte[6]; // file member group id - decimal
private byte[] ar_mode = new byte[8]; // file member mode - octal
private byte[] ar_size = new byte[10]; // file member size - decimal
private byte[] ar_fmag = new byte[2]; // ARFMAG - string to end header
// derived information
String name;
public int somOffset;
public int somSize;
public ARHeader(long offset) throws IOException {
try {
getRandomAccessFile();
file.seek(offset);
file.read(ar_name);
for (int i = 0; i < 16; ++ i) {
if (ar_name[i] == '/') {
name = new String(ar_name, 0, i);
}
}
file.read(ar_date);
file.read(ar_uid);
file.read(ar_gid);
file.read(ar_mode);
file.read(ar_size);
file.read(ar_fmag);
} catch (IOException e) {
dispose();
CCorePlugin.log(e);
}
}
/** Get the name of the object file */
public String getObjectName() {
return name;
}
/** Get the size of the object file . */
public long getSize() {
return somSize;
}
public byte[] getObjectData() throws IOException {
byte[] temp = new byte[somSize];
file = getRandomAccessFile();
file.seek(somOffset);
file.read(temp);
dispose();
return temp;
}
/**
* Create a new SOM object for the object file.
*
* @throws IOException
* Not a valid SOM object file.
* @return A new SOM object.
* @see SOM#SOM( String, long )
*/
public SOM getSOM() throws IOException {
return new SOM(filename, somOffset);
}
}
/**
* Library Symbol Table header
*
* @author vhirsl
*/
public class LSTHeader {
public static final int LST_HEADER_OFFSET = 68;
public static final int LST_HEADER_SIZE = 19 * 4;
// record fields
public short system_id;
public short a_magic;
public int version_id;
public int file_time_sec;
public int file_time_nano;
public int hash_loc;
public int hash_size;
public int module_count;
public int module_limit;
public int dir_loc;
public int export_loc;
public int export_count;
public int import_loc;
public int aux_loc;
public int aux_size;
public int string_loc;
public int string_size;
public int free_list;
public int file_end;
public int checksum;
public LSTHeader() throws IOException {
try {
getRandomAccessFile();
file.seek(LST_HEADER_OFFSET);
byte[] lstRecord = new byte[LST_HEADER_SIZE];
file.readFully(lstRecord);
ReadMemoryAccess memory = new ReadMemoryAccess(lstRecord, false);
system_id = memory.getShort();
a_magic = memory.getShort();
version_id = memory.getInt();
file_time_sec = memory.getInt();
file_time_nano = memory.getInt();
hash_loc = memory.getInt();
hash_size = memory.getInt();
module_count = memory.getInt();
module_limit = memory.getInt();
dir_loc = memory.getInt();
export_loc = memory.getInt();
export_count = memory.getInt();
import_loc = memory.getInt();
aux_loc = memory.getInt();
aux_size = memory.getInt();
string_loc = memory.getInt();
string_size = memory.getInt();
free_list = memory.getInt();
file_end = memory.getInt();
checksum = memory.getInt();
} catch (IOException e) {
dispose();
CCorePlugin.log(e);
}
}
}
/**
* Creates a new <code>AR</code> object from the contents of
* the given file.
*
* @param filename The file to process.
* @throws IOException The file is not a valid archive.
*/
public AR(String filename) throws IOException {
this.filename = filename;
file = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
file.read(ar_magic);
if (!isARHeader(ar_magic)) {
file.close();
throw new IOException(CCorePlugin.getResourceString("Util.exception.invalidArchive")); //$NON-NLS-1$
}
// load a LST header
lstHeader = new LSTHeader();
}
public void dispose() {
try {
if (file != null) {
file.close();
file = null;
}
} catch (IOException e) {
}
}
protected void finalize() throws Throwable {
try {
dispose();
} finally {
super.finalize();
}
}
public static boolean isARHeader(byte[] ident) {
if (ident.length < 8
|| ident[0] != '!'
|| ident[1] != '<'
|| ident[2] != 'a'
|| ident[3] != 'r'
|| ident[4] != 'c'
|| ident[5] != 'h'
|| ident[6] != '>'
|| ident[7] != '\n')
return false;
return true;
}
private RandomAccessFile getRandomAccessFile () throws IOException {
if (file == null) {
file = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
}
return file;
}
/**
* Get an array of all the object file headers for this archive.
*
* @throws IOException
* Unable to process the archive file.
* @return An array of headers, one for each object within the archive.
* @see ARHeader
*/
public ARHeader[] getHeaders() throws IOException {
loadHeaders();
return memberHeaders;
}
/** Load the headers from the file (if required). */
private void loadHeaders() throws IOException {
if (memberHeaders != null)
return;
Vector v = new Vector();
try {
//
// Check for EOF condition
//
// get the SOM directory
long somDirOffset = lstHeader.dir_loc + LSTHeader.LST_HEADER_OFFSET;
// each SOM Directory entry has 2 32bit words: SOM offset from LST and size
int somDirSize = lstHeader.module_limit * 8;
getRandomAccessFile();
file.seek(somDirOffset);
byte[] somDirectory = new byte[somDirSize];
file.readFully(somDirectory);
ReadMemoryAccess memory = new ReadMemoryAccess(somDirectory, false);
for (int i = 0; i < lstHeader.module_limit; ++i) {
int somOffset = memory.getInt();
int somSize = memory.getInt();
ARHeader aHeader = new ARHeader(somOffset-ARHeader.HEADER_SIZE);
aHeader.somOffset = somOffset;
aHeader.somSize = somSize;
v.add(aHeader);
}
} catch (IOException e) {
}
memberHeaders = (ARHeader[]) v.toArray(new ARHeader[v.size()]);
}
public String[] extractFiles(String outdir) throws IOException {
return extractFiles(outdir, null);
}
private String[] extractFiles(String outdir, String[] names) throws IOException {
Vector names_used = new Vector();
String object_name;
int count;
loadHeaders();
count = 0;
for (int i = 0; i < memberHeaders.length; i++) {
object_name = memberHeaders[i].getObjectName();
if (names != null && !stringInStrings(object_name, names))
continue;
object_name = "" + count + "_" + object_name; //$NON-NLS-1$ //$NON-NLS-2$
count++;
byte[] data = memberHeaders[i].getObjectData();
File output = new File(outdir, object_name);
names_used.add(object_name);
RandomAccessFile rfile = new RandomAccessFile(output, "rw"); //$NON-NLS-1$
rfile.write(data);
rfile.close();
}
return (String[]) names_used.toArray(new String[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 toString() {
StringBuffer buffer = new StringBuffer();
if (lstHeader != null) {
buffer.append("LST HEADER VALUES").append(NL); //$NON-NLS-1$
buffer.append("system_id = ").append(lstHeader.system_id).append(NL); //$NON-NLS-1$
buffer.append("a_magic = ").append(lstHeader.a_magic).append(NL); //$NON-NLS-1$
buffer.append("version_id = ").append(lstHeader.version_id).append(NL); //$NON-NLS-1$
buffer.append("module_count = ").append(lstHeader.module_count).append(NL); //$NON-NLS-1$
buffer.append("module_limit = ").append(lstHeader.module_limit).append(NL); //$NON-NLS-1$
buffer.append("dir_loc = ").append(lstHeader.dir_loc).append(NL); //$NON-NLS-1$
for (int i = 0; i < memberHeaders.length; ++i) {
buffer.append("MEMBER HEADER VALUES").append(NL); //$NON-NLS-1$
buffer.append("name = ").append(memberHeaders[i].getObjectName()).append(NL); //$NON-NLS-1$
buffer.append("somOffset = ").append(memberHeaders[i].somOffset).append(NL); //$NON-NLS-1$
buffer.append("somSize = ").append(memberHeaders[i].getSize()).append(NL); //$NON-NLS-1$
}
}
return buffer.toString();
}
public static void main(String[] args) {
try {
AR ar = new AR(args[0]);
ar.getHeaders();
ar.extractFiles(args[1]);
System.out.println(ar);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,570 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.utils.som;
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.utils.coff.ReadMemoryAccess;
/**
* Representation of a HP-UX SOM binary format
*
* @author vhirsl
*/
public class SOM {
public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
String filename;
FileHeader filehdr;
RandomAccessFile rfile;
long startingOffset;
byte[] string_table;
Symbol[] symbols;
/**
* SOM Header record
*
* @author vhirsl
*/
public static class FileHeader {
public final static int FILHSZ = 32*4;
// Consts
public static final short PA_RISC_10 = 0x20b;
public static final short PA_RISC_11 = 0x210;
public static final short PA_RISC_20 = 0x214;
public static final short EXE_SOM_LIB = 0x104; // executable SOM library
public static final short REL_SOM = 0x106; // relocatable SOM
public static final short PRIV_EXEC_SOM = 0x107; // non-sharable, executable SOM
public static final short SHARE_EXEC_SOM = 0x108; // sharable, executable SOM
public static final short SHARE_DEMAND_LOAD_EXE_SOM = 0x10b; // sharable, demand-loadable executable SOM
public static final short DYN_LOAD_LIB = 0x10d; // dynamic load library
public static final short SHARED_LIB = 0x10e; // shared library
public static final short RELOC_SOM_LIB = 0x619; // relocatable SOM library
// Fields
public short system_id; // magic number - system
public short a_magic; // magic number - file type
public int version_id; // version id; format = YYMMDDHH
public long file_time_sec; // system clock - zero if unused
public long file_time_nano; // system clock - zero if unused
public int entry_space; // index of space containing entry point
public int entry_subspace; // index of subspace for entry point
public int entry_offset; // offset of entry point
public int aux_header_location; // auxiliary header location
public int aux_header_size; // auxiliary header size
public int som_length; // length in bytes of entire som
public int presumed_dp; // DP value assumed during compilation
public int space_location; // location in file of space dictionary
public int space_total; // number of space entries
public int subspace_location; // location of subspace entries
public int subspace_total; // number of subspace entries
public int loader_fixup_location; // MPE/iX loader fixup
public int loader_fixup_total; // number of loader fixup records
public int space_strings_location; // file location of string area for space and subspace names
public int space_strings_size; // size of string area for space and subspace names
public int init_array_location; // reserved for use by system
public int init_array_total; // reserved for use by system
public int compiler_location; // location in file of module dictionary
public int compiler_total; // number of modules
public int symbol_location; // location in file of symbol dictionary
public int symbol_total; // number of symbol records
public int fixup_request_location; // location in file of fix-up requests
public int fixup_request_total; // number of fixup requests
public int symbol_strings_location; // file location of string area for module and symbol names
public int symbol_strings_size; // size of string area for module and symbol names
public int unloadable_sp_location; // byte offset of first byte of datafor unloadable spaces
public int unloadable_sp_size; // byte length of data for unloadable spaces
public int checksum;
public FileHeader (RandomAccessFile file) throws IOException {
this(file, file.getFilePointer());
}
public FileHeader (RandomAccessFile file, long offset) throws IOException {
file.seek(offset);
byte[] hdr = new byte[FILHSZ];
file.readFully(hdr);
commonSetup(hdr, false);
}
public FileHeader (byte[] hdr, boolean little) throws IOException {
commonSetup(hdr, little);
}
public void commonSetup(byte[] hdr, boolean little) throws IOException {
if (hdr == null || hdr.length < FILHSZ) {
throw new EOFException(CCorePlugin.getResourceString("Util.exception.arrayToSmall")); //$NON-NLS-1$
}
if (!isSOMHeader(hdr)) {
throw new IOException(CCorePlugin.getResourceString("Util.exception.notSOM")); //$NON-NLS-1$
}
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, little);
system_id = memory.getShort();
a_magic = memory.getShort();
version_id = memory.getInt();
file_time_sec = memory.getInt();
file_time_nano = memory.getInt();
entry_space = memory.getInt();
entry_subspace = memory.getInt();
entry_offset = memory.getInt();
aux_header_location = memory.getInt();
aux_header_size = memory.getInt();
som_length = memory.getInt();
presumed_dp = memory.getInt();
space_location = memory.getInt();
space_total = memory.getInt();
subspace_location = memory.getInt();
subspace_total = memory.getInt();
loader_fixup_location = memory.getInt();
loader_fixup_total = memory.getInt();
space_strings_location = memory.getInt();
space_strings_size = memory.getInt();
init_array_location = memory.getInt();
init_array_total = memory.getInt();
compiler_location = memory.getInt();
compiler_total = memory.getInt();
symbol_location = memory.getInt();
symbol_total = memory.getInt();
fixup_request_location = memory.getInt();
fixup_request_total = memory.getInt();
symbol_strings_location = memory.getInt();
symbol_strings_size = memory.getInt();
unloadable_sp_location = memory.getInt();
unloadable_sp_size = memory.getInt();
checksum = memory.getInt();
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("FILE HEADER VALUES").append(NL); //$NON-NLS-1$
buffer.append("system_id = ").append(system_id).append(NL); //$NON-NLS-1$
buffer.append("a_magic = ").append(a_magic).append(NL); //$NON-NLS-1$
buffer.append("version_id = ").append(version_id).append(NL); //$NON-NLS-1$
buffer.append("file_time_sec = ").append(file_time_sec).append(NL); //$NON-NLS-1$
buffer.append("file_time_nano = ").append(file_time_nano).append(NL); //$NON-NLS-1$
buffer.append("entry_space = ").append(entry_space).append(NL); //$NON-NLS-1$
buffer.append("entry_subspace = ").append(entry_subspace).append(NL); //$NON-NLS-1$
buffer.append("aux_header_location = ").append(aux_header_location).append(NL); //$NON-NLS-1$
buffer.append("aux_header_size = ").append(aux_header_size).append(NL); //$NON-NLS-1$
buffer.append("som_length = ").append(som_length).append(NL); //$NON-NLS-1$
buffer.append("presumed_dp = ").append(presumed_dp).append(NL); //$NON-NLS-1$
buffer.append("space_location = ").append(space_location).append(NL); //$NON-NLS-1$
buffer.append("space_total = ").append(space_total).append(NL); //$NON-NLS-1$
buffer.append("subspace_location = ").append(subspace_location).append(NL); //$NON-NLS-1$
buffer.append("subspace_total = ").append(subspace_total).append(NL); //$NON-NLS-1$
buffer.append("loader_fixup_location = ").append(loader_fixup_location).append(NL); //$NON-NLS-1$
buffer.append("loader_fixup_total = ").append(loader_fixup_total).append(NL); //$NON-NLS-1$
buffer.append("space_strings_location = ").append(space_strings_location).append(NL); //$NON-NLS-1$
buffer.append("space_strings_size = ").append(space_strings_size).append(NL); //$NON-NLS-1$
buffer.append("init_array_location = ").append(init_array_location).append(NL); //$NON-NLS-1$
buffer.append("init_array_total = ").append(init_array_total).append(NL); //$NON-NLS-1$
buffer.append("compiler_location = ").append(compiler_location).append(NL); //$NON-NLS-1$
buffer.append("compiler_total = ").append(compiler_total).append(NL); //$NON-NLS-1$
buffer.append("symbol_location = ").append(symbol_location).append(NL); //$NON-NLS-1$
buffer.append("symbol_total = ").append(symbol_total).append(NL); //$NON-NLS-1$
buffer.append("fixup_request_location = ").append(fixup_request_location).append(NL); //$NON-NLS-1$
buffer.append("fixup_request_total = ").append(fixup_request_total).append(NL); //$NON-NLS-1$
buffer.append("symbol_strings_location = ").append(symbol_strings_location).append(NL); //$NON-NLS-1$
buffer.append("symbol_strings_size = ").append(symbol_strings_size).append(NL); //$NON-NLS-1$
buffer.append("unloadable_sp_location = ").append(unloadable_sp_location).append(NL); //$NON-NLS-1$
buffer.append("unloadable_sp_size = ").append(unloadable_sp_size).append(NL); //$NON-NLS-1$
buffer.append("checksum = ").append(checksum).append(NL); //$NON-NLS-1$
return buffer.toString();
}
}
public class Symbol {
public static final int SYMSZ = 5*4; // 5 words = 20 bytes
// masks
// NOTE: HP-UX denotes bit 0 as a leftmost bit in a word
// following representation denotes bit 0 as a rightmost bit in a word
public static final int B31_MASK = 0x80000000;
public static final int B30_MASK = 0x40000000;
public static final int B29_24_MASK = 0x3f000000;
public static final int B23_20_MASK = 0x00f00000;
public static final int B19_17_MASK = 0x000e0000;
public static final int B16_MASK = 0x00010000;
public static final int B15_MASK = 0x00008000;
public static final int B14_MASK = 0x00004000;
public static final int B13_MASK = 0x00002000;
public static final int B12_MASK = 0x00001000;
public static final int B11_10_MASK = 0x00000C00;
public static final int B9_0_MASK = 0x000003ff;
public static final int B23_0_MASK = 0x00ffffff;
public static final int B7_0_MASK = 0x000000ff;
// symbol type
public static final int NULL = 0; // Invalid symbol record
public static final int ABSOLUTE = 1; // Absolute constant
public static final int DATA = 2; // Normal initialized data
public static final int CODE = 3; // Unspecified code
public static final int PRI_PROG = 4; // Primary program entry point
public static final int SEC_PROG = 5; // Secondary program entry point
public static final int ENTRY = 6; // Any code entry point
public static final int STORAGE = 7; // Uninitialized common data blocks
public static final int STUB = 8; // Import external call stub or a parameter relocation stub
public static final int MODULE = 9; // Source module name
public static final int SYM_EXT = 10; // Extension record of the current entry
public static final int ARG_EXT = 11; // -||-
public static final int MILLICODE = 12; // Millicode routine
public static final int PLABEL = 13; // Export stub for a procedure
public static final int OCT_DIS = 14; // Pointer to translated code segment exists but disabled
public static final int MILLI_EXT = 15; // Address of an external millicode routine
public static final int ST_DATA = 15; // Thread specific data
// symbol scope
public static final int UNSAT = 0; // Import request that has not been satisfied
public static final int EXTERNAL = 1; // Import request linked to a symbol in another SOM
public static final int LOCAL = 2; // The symbol is not exported for use outside the SOM
public static final int UNIVERSAL = 3; // The symbol is exported for use outside the SOM
// fields
public boolean hidden; // W1 b31
public boolean secondary_def; // W1 b30
public int symbol_type; // W1 b29-24
public int symbol_scope; // W1 b23-20
public int check_level; // W1 b19-17
public boolean must_qualify; // W1 b16
public boolean initially_frozen; // W1 b15
public boolean memory_resident; // W1 b14
public boolean is_common; // W1 b13
public boolean dup_common; // W1 b12
public int xleast; // W1 b11-10
public int arg_reloc; // W1 b9-0
public int name_offset; // W2
public int qualifier_name_offset; // W3
public boolean has_long_return; // W4 b31
public boolean no_relocation; // W4 b30
public int symbol_info; // W4 b23-0
public int symbol_value; // W5
public Symbol(RandomAccessFile file) throws IOException {
this(file, file.getFilePointer());
}
public Symbol(RandomAccessFile file, long offset) throws IOException {
file.seek(offset);
byte[] bytes = new byte[SYMSZ];
file.readFully(bytes);
ReadMemoryAccess memory = new ReadMemoryAccess(bytes, false); // big endian
// first word
int word = memory.getInt();
hidden = (word & B31_MASK) != 0;
secondary_def = (word & B30_MASK) != 0;
symbol_type = (word & B29_24_MASK) >> 24;
symbol_scope = (word & B23_20_MASK) >> 20;
check_level = (word & B19_17_MASK) >> 17;
must_qualify = (word & B16_MASK) != 0;
initially_frozen = (word & B15_MASK) != 0;
memory_resident = (word & B14_MASK) != 0;
is_common = (word & B13_MASK) != 0;
dup_common = (word & B12_MASK) != 0;
xleast = (word & B11_10_MASK) >> 10;
arg_reloc = word & B9_0_MASK;
// second word
name_offset = memory.getInt();
// third word
qualifier_name_offset = memory.getInt();
// fourth word
word = memory.getInt();
has_long_return = (word & B31_MASK) != 0;
no_relocation = (word & B30_MASK) != 0;
symbol_info = word & B23_0_MASK;
// fifth word
symbol_value = memory.getInt();
// check for symbol extension record and descriptor array records
if (check_level >= 1) {
// bytes = new byte[SYMSZ];
file.readFully(bytes);
memory = new ReadMemoryAccess(bytes, false); // big endian
// an extension record is present (size 5 words = 20 bytes)
word = memory.getInt();
int num_args = word & B7_0_MASK;
// check for argument descriptor arrays
if (num_args > 3 && check_level >=3) {
int num_descs = (num_args-3)%4 == 0 ? (num_args-3)/4 : (num_args-3)/4 + 1;
for (int i = 0; i < num_descs; ++ i) {
file.readFully(bytes);
}
}
}
}
public String getName(byte[] table) {
if (qualifier_name_offset != 0) {
byte[] len = new byte[4];
System.arraycopy(table, qualifier_name_offset-4, len, 0, 4);
ReadMemoryAccess memory = new ReadMemoryAccess(len, false); // big endian
int length = memory.getInt();
return new String(table, qualifier_name_offset, length);
}
if (name_offset != 0) {
byte[] len = new byte[4];
System.arraycopy(table, name_offset-4, len, 0, 4);
ReadMemoryAccess memory = new ReadMemoryAccess(len, false); // big endian
int length = memory.getInt();
return new String(table, name_offset, length);
}
return ""; //$NON-NLS-1$
}
public boolean isFunction() {
return (symbol_type == PRI_PROG ||
(symbol_type == ENTRY && symbol_scope != LOCAL));
}
public boolean isVariable() {
return ((symbol_type == DATA && symbol_scope != LOCAL) ||
symbol_type == STORAGE);
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("SYMBOL TABLE ENTRY").append(NL); //$NON-NLS-1$
buffer.append("symbol_name = ");
try {
buffer.append(getName(getStringTable())).append(NL);
}
catch (IOException e) {
buffer.append("I/O error"); //$NON-NLS-1$
}
buffer.append("symbol_value = ").append(symbol_value).append(NL); //$NON-NLS-1$
buffer.append("symbol_type = ").append(symbol_type).append(NL); //$NON-NLS-1$
buffer.append("symbol_scope = ").append(symbol_scope).append(NL); //$NON-NLS-1$
return buffer.toString();
}
}
public static class Attribute {
public static final int SOM_TYPE_EXE = 1;
public static final int SOM_TYPE_SHLIB = 2;
public static final int SOM_TYPE_OBJ = 3;
public static final int SOM_TYPE_CORE = 4;
String cpu;
int type;
boolean bDebug;
boolean isle;
public String getCPU() {
return cpu;
}
public int getType() {
return type;
}
public boolean hasDebug() {
return bDebug;
}
public boolean isLittleEndian() {
return isle;
}
}
/*
* SOM class implementation
*/
// A hollow entry, to be used with caution in controlled situations
protected SOM() {
}
public SOM(String filename) throws IOException {
this(filename, 0);
}
public SOM(String filename, long offset) throws IOException {
this.filename = filename;
commonSetup(new RandomAccessFile(filename, "r"), offset);
}
void commonSetup(RandomAccessFile file, long offset) throws IOException {
startingOffset = offset;
rfile = file;
try {
filehdr = new FileHeader(rfile, startingOffset);
} finally {
dispose();
}
}
public void dispose() throws IOException {
if (rfile != null) {
rfile.close();
rfile = null;
}
}
RandomAccessFile getRandomAccessFile () throws IOException {
if (rfile == null) {
rfile = new RandomAccessFile(filename, "r"); //$NON-NLS-1$
}
return rfile;
}
public FileHeader getFileHeader() throws IOException {
return filehdr;
}
public Attribute getAttributes() {
Attribute attrib = new Attribute();
// Machine type.
switch (filehdr.system_id) {
case FileHeader.PA_RISC_10:
attrib.cpu = "pa-risc_1.0"; //$NON-NLS-1$
break;
case FileHeader.PA_RISC_11:
attrib.cpu = "pa-risc_1.1"; //$NON-NLS-1$
break;
case FileHeader.PA_RISC_20:
attrib.cpu = "pa-risc_2.0"; //$NON-NLS-1$
break;
default:
attrib.cpu = "unknown"; //$NON-NLS-1$
break;
}
/* SOM characteristics, FileHeader.a_magic. */
switch (filehdr.a_magic) {
case FileHeader.EXE_SOM_LIB:
case FileHeader.PRIV_EXEC_SOM:
case FileHeader.SHARE_EXEC_SOM:
case FileHeader.SHARE_DEMAND_LOAD_EXE_SOM:
attrib.type = Attribute.SOM_TYPE_EXE;
break;
case FileHeader.DYN_LOAD_LIB:
case FileHeader.SHARED_LIB:
attrib.type = Attribute.SOM_TYPE_SHLIB;
break;
default:
attrib.type = Attribute.SOM_TYPE_OBJ;
}
// For HP-UX SOM always assume big endian unless otherwise.
attrib.isle = false;
// No debug information.
if (filehdr.symbol_location == 0 && filehdr.symbol_total == 0) {
attrib.bDebug = false;
} else {
attrib.bDebug = true;
}
return attrib;
}
public Symbol[] getSymbols() throws IOException {
if (symbols == null) {
long offset = startingOffset + getFileHeader().symbol_location;
getRandomAccessFile();
rfile.seek(offset);
int numSymbols = getFileHeader().symbol_total;
ArrayList symList = new ArrayList(numSymbols);
for (int i = 0; i < numSymbols; ++i) {
Symbol v = new Symbol(rfile);
symList.add(v);
}
symbols = (Symbol[]) symList.toArray(new Symbol[symList.size()]);
}
return symbols;
}
public byte[] getStringTable() throws IOException {
if (string_table == null) {
if (getFileHeader().symbol_strings_size > 0) {
getRandomAccessFile();
long offset = startingOffset+ getFileHeader().symbol_strings_location;
rfile.seek(offset);
string_table = new byte[getFileHeader().symbol_strings_size];
rfile.readFully(string_table);
}
else {
string_table = new byte[0];
}
}
return string_table;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
try {
FileHeader header = null;
header = getFileHeader();
if (header != null) {
buffer.append(header);
}
getSymbols();
for (int i = 0; i < symbols.length; ++i) {
buffer.append(symbols[i]);
}
} catch (IOException e) {
e.printStackTrace();
}
return buffer.toString();
}
/**
* @param hints
* @return
*/
public static boolean isSOMHeader(byte[] hints) {
if (hints != null && hints[0] == 0x02 &&
(hints[1] == (byte)0xb || hints[1] == (byte)0x10 || hints[1] == (byte)0x14) ) {
return true;
}
return false;
}
/**
* @param hints
* @return
* @throws IOException
*/
public static Attribute getAttributes(byte[] hints) throws IOException {
SOM emptyXCoff = new SOM();
emptyXCoff.filehdr = new SOM.FileHeader(hints, false); // big endian
Attribute attribute = emptyXCoff.getAttributes();
emptyXCoff.dispose();
return attribute;
}
/**
* @param file
* @return
* @throws IOException
*/
public static Attribute getAttributes(String file) throws IOException {
SOM xcoff = new SOM(file);
Attribute attribute = xcoff.getAttributes();
xcoff.dispose();
return attribute;
}
public static void main(String[] args) {
try {
SOM som = new SOM(args[0]);
System.out.println(som);
}
catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,107 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.utils.som.parser;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IBinaryParser;
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
import org.eclipse.core.runtime.IPath;
import org.eclipse.cdt.utils.CPPFilt;
import org.eclipse.cdt.utils.Symbol;
import org.eclipse.cdt.utils.som.AR;
import org.eclipse.cdt.utils.som.SOM;
/**
* A member of a SOM archive
*
* @author vhirsl
*/
public class ARMember extends SOMBinaryObject {
private AR.ARHeader header;
/**
* @param parser
* @param path
*/
public ARMember(IBinaryParser parser, IPath path, AR.ARHeader header) {
super(parser, path);
this.header = header;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.som.parser.SOMBinaryObject#addSymbols(org.eclipse.cdt.utils.som.SOM.Symbol[], byte[], org.eclipse.cdt.utils.Addr2line, org.eclipse.cdt.utils.CPPFilt, org.eclipse.cdt.utils.CygPath, java.util.List)
*/
protected void addSymbols(SOM.Symbol[] peSyms, byte[] table, List list) {
CPPFilt cppfilt = getCPPFilt();
for (int i = 0; i < peSyms.length; i++) {
if (peSyms[i].isFunction() || peSyms[i].isVariable()) {
String name = peSyms[i].getName(table);
if (name == null || name.trim().length() == 0 ||
!Character.isJavaIdentifierStart(name.charAt(0))) {
continue;
}
if (cppfilt != null) {
try {
name = cppfilt.getFunction(name);
} catch (IOException e1) {
cppfilt = null;
}
}
Symbol sym = new Symbol(this, name, peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE, peSyms[i].symbol_value, 1);
list.add(sym);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.som.parser.SOMBinaryObject#getSOM()
*/
protected SOM getSOM() throws IOException {
if (header != null) {
return header.getSOM();
}
throw new IOException(CCorePlugin.getResourceString("Util.exception.noFileAssociation")); //$NON-NLS-1$
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getContents()
*/
public InputStream getContents() {
InputStream stream = null;
if (path != null && header != null) {
try {
stream = new ByteArrayInputStream(header.getObjectData());
} catch (IOException e) {
}
}
if (stream == null) {
stream = super.getContents();
}
return stream;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getName()
*/
public String getName() {
if (header != null) {
return header.getObjectName();
}
return ""; //$NON-NLS-1$
}
}

View file

@ -0,0 +1,74 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.utils.som.parser;
import java.io.IOException;
import java.util.ArrayList;
import org.eclipse.cdt.core.IBinaryParser;
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.cdt.utils.BinaryFile;
import org.eclipse.cdt.utils.som.AR;
import org.eclipse.core.runtime.IPath;
/**
* SOM binary archive
*
* @author vhirsl
*/
public class BinaryArchive extends BinaryFile implements IBinaryArchive {
private ArrayList children;
/**
* @param parser
* @param path
* @throws IOException
*/
public BinaryArchive(IBinaryParser parser, IPath path) throws IOException {
super(parser, path);
new AR(path.toOSString()).dispose(); // check file type
children = new ArrayList(5);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
*/
public int getType() {
return IBinaryFile.ARCHIVE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryArchive#getObjects()
*/
public IBinaryObject[] getObjects() {
if (hasChanged()) {
children.clear();
AR ar = null;
try {
ar = new AR(getPath().toOSString());
AR.ARHeader[] headers = ar.getHeaders();
for (int i = 0; i < headers.length; i++) {
IBinaryObject bin = new ARMember(getBinaryParser(), getPath(), headers[i]);
children.add(bin);
}
} catch (IOException e) {
//e.printStackTrace();
}
if (ar != null) {
ar.dispose();
}
children.trimToSize();
}
return (IBinaryObject[]) children.toArray(new IBinaryObject[0]);
}
}

View file

@ -0,0 +1,265 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.utils.som.parser;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.core.IBinaryParser;
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
import org.eclipse.cdt.utils.Addr2line;
import org.eclipse.cdt.utils.BinaryObjectAdapter;
import org.eclipse.cdt.utils.CPPFilt;
import org.eclipse.cdt.utils.Objdump;
import org.eclipse.cdt.utils.som.SOM;
import org.eclipse.cdt.utils.som.parser.SOMParser;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* Binary file in HP-UX SOM format
*
* @author vhirsl
*/
public class SOMBinaryObject extends BinaryObjectAdapter {
Addr2line addr2line;
BinaryObjectInfo info;
ISymbol[] symbols;
/**
* @param parser
* @param path
*/
public SOMBinaryObject(IBinaryParser parser, IPath path) {
super(parser, path);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbols()
*/
public ISymbol[] getSymbols() {
if (hasChanged() || symbols == null) {
try {
loadAll();
} catch (IOException e) {
symbols = NO_SYMBOLS;
}
}
return symbols;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.BinaryObjectAdapter#getBinaryObjectInfo()
*/
protected BinaryObjectInfo getBinaryObjectInfo() {
if (hasChanged() || info == null) {
try {
loadInfo();
} catch (IOException e) {
info = new BinaryObjectInfo();
}
}
return info;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
*/
public int getType() {
return IBinaryFile.OBJECT;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getContents()
*/
public InputStream getContents() {
InputStream stream = null;
Objdump objdump = getObjdump();
if (objdump != null) {
try {
byte[] contents = objdump.getOutput();
stream = new ByteArrayInputStream(contents);
} catch (IOException e) {
// Nothing
}
}
if (stream == null) {
stream = super.getContents();
}
return stream;
}
protected SOM getSOM() throws IOException {
return new SOM(getPath().toOSString());
}
protected void loadAll() throws IOException {
SOM som = null;
try {
som = getSOM();
loadInfo(som);
loadSymbols(som);
} finally {
if (som != null) {
som.dispose();
}
}
}
protected void loadInfo() throws IOException {
SOM som = null;
try {
som = getSOM();
loadInfo(som);
} finally {
if (som != null) {
som.dispose();
}
}
}
protected void loadInfo(SOM som) throws IOException {
info = new BinaryObjectInfo();
SOM.Attribute attribute = som.getAttributes();
info.isLittleEndian = attribute.isLittleEndian();
info.hasDebug = attribute.hasDebug();
info.cpu = attribute.getCPU();
}
protected void loadSymbols(SOM som) throws IOException {
ArrayList list = new ArrayList();
SOM.Symbol[] peSyms = som.getSymbols();
byte[] table = som.getStringTable();
addSymbols(peSyms, table, list);
symbols = (ISymbol[])list.toArray(NO_SYMBOLS);
Arrays.sort(symbols);
list.clear();
}
protected void addSymbols(SOM.Symbol[] peSyms, byte[] table, List list) {
CPPFilt cppfilt = getCPPFilt();
Addr2line addr2line = getAddr2line(false);
for (int i = 0; i < peSyms.length; i++) {
if (peSyms[i].isFunction() || peSyms[i].isVariable()) {
String name = peSyms[i].getName(table);
if (name == null || name.trim().length() == 0 ||
!Character.isJavaIdentifierStart(name.charAt(0))) {
continue;
}
int type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE;
int addr = peSyms[i].symbol_value;
int size = 4;
if (cppfilt != null) {
try {
name = cppfilt.getFunction(name);
} catch (IOException e1) {
cppfilt = null;
}
}
if (addr2line != null) {
try {
String filename = addr2line.getFileName(addr);
// Addr2line returns the funny "??" when it can not find the file.
if (filename != null && filename.equals("??")) { //$NON-NLS-1$
filename = null;
}
IPath file = filename != null ? new Path(filename) : Path.EMPTY;
int startLine = addr2line.getLineNumber(addr);
int endLine = addr2line.getLineNumber(addr + size - 1);
list.add(new SomSymbol(this, name, type, addr, size, file, startLine, endLine));
} catch (IOException e) {
addr2line = null;
// the symbol still needs to be added
list.add(new SomSymbol(this, name, type, addr, size));
}
} else {
list.add(new SomSymbol(this, name, type, addr, size));
}
}
}
if (cppfilt != null) {
cppfilt.dispose();
}
if (addr2line != null) {
addr2line.dispose();
}
}
public Addr2line getAddr2line(boolean autodisposing) {
if (!autodisposing) {
SOMParser parser = (SOMParser) getBinaryParser();
return parser.getAddr2line(getPath());
}
if (addr2line == null) {
SOMParser parser = (SOMParser) getBinaryParser();
addr2line = parser.getAddr2line(getPath());
if (addr2line != null) {
timestamp = System.currentTimeMillis();
Runnable worker = new Runnable() {
public void run() {
long diff = System.currentTimeMillis() - timestamp;
while (diff < 10000) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
break;
}
diff = System.currentTimeMillis() - timestamp;
}
stopAddr2Line();
}
};
new Thread(worker, "Addr2line Reaper").start(); //$NON-NLS-1$
}
} else {
timestamp = System.currentTimeMillis();
}
return addr2line;
}
synchronized void stopAddr2Line() {
if (addr2line != null) {
addr2line.dispose();
}
addr2line = null;
}
protected CPPFilt getCPPFilt() {
SOMParser parser = (SOMParser)getBinaryParser();
return parser.getCPPFilt();
}
protected Objdump getObjdump() {
SOMParser parser = (SOMParser)getBinaryParser();
return parser.getObjdump(getPath());
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
*/
public Object getAdapter(Class adapter) {
if (adapter == Addr2line.class) {
return getAddr2line(false);
} else if (adapter == CPPFilt.class) {
return getCPPFilt();
}
return super.getAdapter(adapter);
}
}

View file

@ -0,0 +1,267 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.utils.som.parser;
import java.io.EOFException;
import java.io.IOException;
import org.eclipse.cdt.core.AbstractCExtension;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IBinaryParser;
import org.eclipse.cdt.core.ICExtensionReference;
import org.eclipse.cdt.utils.Addr2line;
import org.eclipse.cdt.utils.CPPFilt;
import org.eclipse.cdt.utils.IGnuToolFactory;
import org.eclipse.cdt.utils.Objdump;
import org.eclipse.cdt.utils.som.AR;
import org.eclipse.cdt.utils.som.SOM;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* HP-UX SOM binary parser
*
* @author vhirsl
*/
public class SOMParser extends AbstractCExtension implements IBinaryParser, IGnuToolFactory {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser#getBinary(byte[], org.eclipse.core.runtime.IPath)
*/
public IBinaryFile getBinary(byte[] hints, IPath path) throws IOException {
if (path == null) {
throw new IOException(CCorePlugin.getResourceString("Util.exception.nullPath")); //$NON-NLS-1$
}
IBinaryFile binary = null;
if (isBinary(hints, path)) {
try {
SOM.Attribute attribute = null;
if (hints != null && hints.length > 0) {
try {
attribute = SOM.getAttributes(hints);
} catch (EOFException eof) {
// continue, the array was to small.
}
}
//Take a second run at it if the data array failed.
if(attribute == null) {
attribute = SOM.getAttributes(path.toOSString());
}
if (attribute != null) {
switch (attribute.getType()) {
case SOM.Attribute.SOM_TYPE_EXE :
binary = createBinaryExecutable(path);
break;
case SOM.Attribute.SOM_TYPE_SHLIB :
binary = createBinaryShared(path);
break;
case SOM.Attribute.SOM_TYPE_OBJ :
binary = createBinaryObject(path);
break;
case SOM.Attribute.SOM_TYPE_CORE :
binary = createBinaryCore(path);
break;
}
}
} catch (IOException e) {
binary = createBinaryArchive(path);
}
}
return binary;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser#getBinary(org.eclipse.core.runtime.IPath)
*/
public IBinaryFile getBinary(IPath path) throws IOException {
return getBinary(null, path);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser#getFormat()
*/
public String getFormat() {
return "SOM"; //$NON-NLS-1$
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath)
*/
public boolean isBinary(byte[] hints, IPath path) {
return SOM.isSOMHeader(hints) || AR.isARHeader(hints);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser#getHintBufferSize()
*/
public int getHintBufferSize() {
return 512; // size of file header
}
/**
* @param path
* @return
*/
private IBinaryFile createBinaryExecutable(IPath path) {
return new SOMBinaryObject(this, path) {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
*/
public int getType() {
return IBinaryFile.EXECUTABLE;
}
};
}
/**
* @param path
* @return
*/
private IBinaryFile createBinaryShared(IPath path) {
return new SOMBinaryObject(this, path) {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
*/
public int getType() {
return IBinaryFile.SHARED;
}
};
}
/**
* @param path
* @return
*/
private IBinaryFile createBinaryObject(IPath path) {
return new SOMBinaryObject(this, path);
}
/**
* @param path
* @return
*/
private IBinaryFile createBinaryCore(IPath path) {
return new SOMBinaryObject(this, path) {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType()
*/
public int getType() {
return IBinaryFile.CORE;
}
};
}
/**
* @param path
* @return
* @throws IOException
*/
private IBinaryFile createBinaryArchive(IPath path) throws IOException {
return new BinaryArchive(this, path);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.IGnuToolFactory#getAddr2line(org.eclipse.core.runtime.IPath)
*/
public Addr2line getAddr2line(IPath path) {
IPath addr2LinePath = getAddr2linePath();
Addr2line addr2line = null;
if (addr2LinePath != null && !addr2LinePath.isEmpty()) {
try {
addr2line = new Addr2line(addr2LinePath.toOSString(), path.toOSString());
} catch (IOException e1) {
}
}
return addr2line;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.IGnuToolFactory#getCPPFilt()
*/
public CPPFilt getCPPFilt() {
IPath cppFiltPath = getCPPFiltPath();
CPPFilt cppfilt = null;
if (cppFiltPath != null && ! cppFiltPath.isEmpty()) {
try {
cppfilt = new CPPFilt(cppFiltPath.toOSString());
} catch (IOException e2) {
}
}
return cppfilt;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.utils.IGnuToolFactory#getObjdump(org.eclipse.core.runtime.IPath)
*/
public Objdump getObjdump(IPath path) {
IPath objdumpPath = getObjdumpPath();
String objdumpArgs = getObjdumpArgs();
Objdump objdump = null;
if (objdumpPath != null && !objdumpPath.isEmpty()) {
try {
objdump = new Objdump(objdumpPath.toOSString(), objdumpArgs, path.toOSString());
} catch (IOException e1) {
}
}
return objdump;
}
protected IPath getAddr2linePath() {
ICExtensionReference ref = getExtensionReference();
String value = ref.getExtensionData("addr2line"); //$NON-NLS-1$
if (value == null || value.length() == 0) {
value = "addr2line"; //$NON-NLS-1$
}
return new Path(value);
}
protected IPath getObjdumpPath() {
ICExtensionReference ref = getExtensionReference();
String value = ref.getExtensionData("objdump"); //$NON-NLS-1$
if (value == null || value.length() == 0) {
value = "objdump"; //$NON-NLS-1$
}
return new Path(value);
}
protected String getObjdumpArgs() {
ICExtensionReference ref = getExtensionReference();
String value = ref.getExtensionData("objdumpArgs"); //$NON-NLS-1$
if (value == null || value.length() == 0) {
value = ""; //$NON-NLS-1$
}
return value;
}
protected IPath getCPPFiltPath() {
ICExtensionReference ref = getExtensionReference();
String value = ref.getExtensionData("c++filt"); //$NON-NLS-1$
if (value == null || value.length() == 0) {
value = "c++filt"; //$NON-NLS-1$
}
return new Path(value);
}
protected IPath getStripPath() {
ICExtensionReference ref = getExtensionReference();
String value = ref.getExtensionData("strip"); //$NON-NLS-1$
if (value == null || value.length() == 0) {
value = "strip"; //$NON-NLS-1$
}
return new Path(value);
}
}

View file

@ -0,0 +1,69 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.utils.som.parser;
import java.io.IOException;
import org.eclipse.cdt.utils.Addr2line;
import org.eclipse.cdt.utils.BinaryObjectAdapter;
import org.eclipse.cdt.utils.Symbol;
import org.eclipse.core.runtime.IPath;
/**
* SOM symbol specialization
*
* @author vhirsl
*/
public class SomSymbol extends Symbol {
/**
* @param binary
* @param name
* @param type
* @param addr
* @param size
* @param sourceFile
* @param startLine
* @param endLine
*/
public SomSymbol(BinaryObjectAdapter binary, String name, int type, long addr, long size, IPath sourceFile, int startLine, int endLine) {
super(binary, name, type, addr, size, sourceFile, startLine, endLine);
// TODO Auto-generated constructor stub
}
/**
* @param binary
* @param name
* @param type
* @param addr
* @param size
*/
public SomSymbol(BinaryObjectAdapter binary, String name, int type, long addr, long size) {
super(binary, name, type, addr, size);
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getLineNumber(long)
*/
public int getLineNumber(long offset) {
int line = -1;
Addr2line addr2line = ((SOMBinaryObject)binary).getAddr2line(true);
if (addr2line != null) {
try {
return addr2line.getLineNumber(getAddress() + offset);
} catch (IOException e) {
// ignore
}
}
return line;
}
}

View file

@ -34,7 +34,7 @@ public class AR {
private MemberHeader[] memberHeaders;
/**
* TODO Provide description
* Content of an archive in AIX XCOFF32 format
*
* @author vhirsl
*/
@ -252,7 +252,7 @@ public class AR {
}
/**
* Create an new XCOFF32 object for the object file.
* Create a new XCOFF32 object for the object file.
*
* @throws IOException
* Not a valid XCOFF32 object file.
@ -370,7 +370,7 @@ public class AR {
try {
AR ar = new AR(args[0]);
ar.getHeaders();
ar.extractFiles(args[0]);
ar.extractFiles(args[1]);
System.out.println(ar);
} catch (IOException e) {
e.printStackTrace();

View file

@ -21,7 +21,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.utils.coff.ReadMemoryAccess;
/**
* TODO Provide description
* Representation of AIX XCOFF32 binary format
*
* @author vhirsl
*/

View file

@ -30,7 +30,7 @@ import org.eclipse.core.runtime.IPath;
* @author vhirsl
*/
public class ARMember extends XCOFFBinaryObject {
AR.MemberHeader header;
private AR.MemberHeader header;
/**
* @param parser

View file

@ -27,7 +27,7 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* TODO Provide description
* Binary file in AIX XCOFF32 format
*
* @author vhirsl
*/
@ -105,7 +105,6 @@ public class XCOFFBinaryObject extends BinaryObjectAdapter {
return stream;
}
protected XCoff32 getXCoff32() throws IOException {
return new XCoff32(getPath().toOSString());
}
@ -189,6 +188,8 @@ public class XCOFFBinaryObject extends BinaryObjectAdapter {
list.add(new XCoffSymbol(this, name, type, addr, size, file, startLine, endLine));
} catch (IOException e) {
addr2line = null;
// the symbol still needs to be added
list.add(new XCoffSymbol(this, name, type, addr, size));
}
} else {
list.add(new XCoffSymbol(this, name, type, addr, size));