The Micro-Executable Format support (experimental).
This commit is contained in:
parent
874217b5b7
commit
1f1f2e12ed
6
tools/z80/java/.classpath
Normal file
6
tools/z80/java/.classpath
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
1
tools/z80/java/.cvsignore
Normal file
1
tools/z80/java/.cvsignore
Normal file
|
@ -0,0 +1 @@
|
|||
bin
|
17
tools/z80/java/.project
Normal file
17
tools/z80/java/.project
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.markn.contiki.z80</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
53
tools/z80/java/src/org/markn/contiki/z80/linker/Area.java
Normal file
53
tools/z80/java/src/org/markn/contiki/z80/linker/Area.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.markn.contiki.z80.linker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class Area {
|
||||
private short _offset;
|
||||
private int _index;
|
||||
private String _name;
|
||||
private int _size;
|
||||
/**
|
||||
* Line data.
|
||||
*/
|
||||
private List<Line> _lines;
|
||||
|
||||
public Area(int index, String name, int size) {
|
||||
_index = index;
|
||||
_name = name;
|
||||
_size = size;
|
||||
_lines = new ArrayList<Line>();
|
||||
}
|
||||
public short getOffset() {
|
||||
return _offset;
|
||||
}
|
||||
public int getIndex() {
|
||||
return _index;
|
||||
}
|
||||
public String getName() {
|
||||
return _name;
|
||||
}
|
||||
public int getSize() {
|
||||
return _size;
|
||||
}
|
||||
public void setOffset(short offset) {
|
||||
_offset = offset;
|
||||
}
|
||||
public void addLine(Line line) {
|
||||
_lines.add(line);
|
||||
}
|
||||
public void relocate(Objfile object, byte[] image) {
|
||||
for (Line line: _lines) {
|
||||
line.fill(object, image);
|
||||
}
|
||||
}
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer(120);
|
||||
buf.append(_name);
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
132
tools/z80/java/src/org/markn/contiki/z80/linker/Line.java
Normal file
132
tools/z80/java/src/org/markn/contiki/z80/linker/Line.java
Normal file
|
@ -0,0 +1,132 @@
|
|||
package org.markn.contiki.z80.linker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Line {
|
||||
private static final Pattern WORD = Pattern.compile("([\\dA-F]{2})\\s([\\dA-F]{2})");
|
||||
private static final Pattern BYTE = Pattern.compile("([\\dA-F]{2})");
|
||||
|
||||
private class Relocation {
|
||||
private int _mode;
|
||||
private int _offset;
|
||||
// area index(!S) or symbol index(S)
|
||||
private int _symbol;
|
||||
}
|
||||
|
||||
private Area _area;
|
||||
private int _address;
|
||||
private List<Short> _bytes;
|
||||
private List<Relocation> _relocs;
|
||||
|
||||
public Line(Objfile object, String tline, String rline) {
|
||||
_relocs = new ArrayList<Relocation>(16);
|
||||
_bytes = new ArrayList<Short>(16);
|
||||
rline = rline.substring(8);
|
||||
int areaindex = getWord(rline);
|
||||
_area = object.getArea(areaindex);
|
||||
if (_area == null) {
|
||||
throw new IllegalArgumentException("no such area:" + areaindex);
|
||||
}
|
||||
_area.addLine(this);
|
||||
tline = tline.substring(2);
|
||||
_address = getWord(tline);
|
||||
tline = tline.substring(3);
|
||||
while (true) {
|
||||
if (tline.length() < 3) {
|
||||
break;
|
||||
}
|
||||
tline = tline.substring(3);
|
||||
_bytes.add(getByte(tline));
|
||||
}
|
||||
// relocation line
|
||||
while (true) {
|
||||
if (rline.length() < 6) {
|
||||
break;
|
||||
}
|
||||
Relocation reloc = new Relocation();
|
||||
_relocs.add(reloc);
|
||||
rline = rline.substring(6);
|
||||
reloc._mode = getByte(rline);
|
||||
rline = rline.substring(3);
|
||||
reloc._offset = getByte(rline) - 2;
|
||||
rline = rline.substring(3);
|
||||
reloc._symbol = getWord(rline);
|
||||
}
|
||||
}
|
||||
private int getWord(String line) {
|
||||
Matcher m = WORD.matcher(line);
|
||||
if (!m.find()) {
|
||||
return -1;
|
||||
}
|
||||
String hexstr = m.group(2) + m.group(1);
|
||||
return Integer.parseInt(hexstr, 16);
|
||||
}
|
||||
|
||||
private short getByte(String line) {
|
||||
Matcher m = BYTE.matcher(line);
|
||||
if (!m.find()) {
|
||||
return -1;
|
||||
}
|
||||
String hexstr = m.group(1);
|
||||
return Short.parseShort(hexstr, 16);
|
||||
}
|
||||
public void fill(Objfile object, byte[] image) {
|
||||
int address = _address + _area.getOffset();
|
||||
for (Relocation reloc : _relocs) {
|
||||
int target = 0;
|
||||
byte mode = 0; // Ext/Int MSB/LSB Byte/Word
|
||||
RelocationInformation info = new RelocationInformation();
|
||||
if ((reloc._mode & 2) > 0) {
|
||||
// external
|
||||
Symbol symbol = object.getSymbol(reloc._symbol);
|
||||
target = symbol.calcOffset();
|
||||
System.out.printf("%s %04X=>%04X\n", symbol, symbol.getOffset(), target);
|
||||
if (symbol.isAbsolute()) {
|
||||
mode |= 0x80;
|
||||
}
|
||||
} else {
|
||||
// internal
|
||||
Area area = object.getArea(reloc._symbol);
|
||||
int offset = area.getOffset();
|
||||
short source = (short) ((_bytes.get(reloc._offset + 1) << 8) + _bytes.get(reloc._offset));
|
||||
target = (short) (source + offset);
|
||||
// TODO: save relocation information
|
||||
System.out.printf("%s:%04X=>%04X\n", area, source, target);
|
||||
}
|
||||
info.setAddress(address);
|
||||
if ((reloc._mode & 1) > 0) {
|
||||
// byte mode
|
||||
if ((reloc._mode & 128) > 0) {
|
||||
// MSB
|
||||
mode |= 0x60;
|
||||
_bytes.set(reloc._offset, (short) (target >> 8));
|
||||
_bytes.set(reloc._offset + 1, (short) -1);
|
||||
} else {
|
||||
// LSB
|
||||
mode |= 0x20;
|
||||
_bytes.set(reloc._offset, (short) -1);
|
||||
_bytes.set(reloc._offset, (short) (target & 0xff));
|
||||
}
|
||||
address++;
|
||||
} else {
|
||||
// word mode
|
||||
_bytes.set(reloc._offset, (short) (target & 0xff));
|
||||
_bytes.set(reloc._offset + 1, (short) (target >> 8));
|
||||
address += 2;
|
||||
}
|
||||
info.setMode(mode);
|
||||
info.setData(target);
|
||||
object.getLinker().addRelocation(info);
|
||||
}
|
||||
address = _address + _area.getOffset();
|
||||
for (int data : _bytes) {
|
||||
if (data >= 0) {
|
||||
image[address++] = (byte) data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
192
tools/z80/java/src/org/markn/contiki/z80/linker/Linker.java
Normal file
192
tools/z80/java/src/org/markn/contiki/z80/linker/Linker.java
Normal file
|
@ -0,0 +1,192 @@
|
|||
package org.markn.contiki.z80.linker;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Linker {
|
||||
private static final String _DATA = "_DATA";
|
||||
|
||||
private static final String _GSINIT = "_GSINIT";
|
||||
|
||||
private static final String _CODE = "_CODE";
|
||||
|
||||
private static final Pattern SYMLINE = Pattern.compile("^00:([\\dA-F]{4})\\s(\\w+)");
|
||||
|
||||
public static void main(String[] arg) throws IOException {
|
||||
File target = new File(arg[0]);
|
||||
if (!target.exists()) {
|
||||
System.out.println(arg[0] + " is no exist.");
|
||||
return;
|
||||
}
|
||||
Linker linker = new Linker();
|
||||
linker.prepare();
|
||||
linker.make(target);
|
||||
}
|
||||
|
||||
private Map<String, Symbol> _symbols;
|
||||
|
||||
private Map<File, Objfile> _objfiles;
|
||||
|
||||
private List<RelocationInformation> _relocations;
|
||||
|
||||
public Linker() {
|
||||
_symbols = new HashMap<String, Symbol>();
|
||||
_objfiles = new HashMap<File, Objfile>();
|
||||
_relocations = new ArrayList<RelocationInformation>();
|
||||
}
|
||||
|
||||
private void prepare() throws IOException {
|
||||
loadSymfile("contiki.sym");
|
||||
loadLibfile("contiki-pc-6001.lib");
|
||||
loadLibfile("c:/dev/sdcc/lib/z80/z80.lib");
|
||||
}
|
||||
|
||||
private void make(File file) throws IOException {
|
||||
List<Objfile> required = new ArrayList<Objfile>();
|
||||
Objfile object = _objfiles.get(file);
|
||||
make(required, object);
|
||||
short codeSize = 0;
|
||||
for (Objfile obj : required) {
|
||||
obj.setAreaOffset(_CODE, codeSize);
|
||||
codeSize += obj.getAreaSize(_CODE);
|
||||
}
|
||||
short gsinitSize = 0;
|
||||
short gsinitOffset = codeSize;
|
||||
for (Objfile obj : required) {
|
||||
obj.setAreaOffset(_GSINIT, gsinitOffset);
|
||||
gsinitSize += obj.getAreaSize(_GSINIT);
|
||||
gsinitOffset += obj.getAreaSize(_GSINIT);
|
||||
}
|
||||
// add space for C9 (ret)
|
||||
gsinitSize++;
|
||||
gsinitOffset++;
|
||||
short dataSize = 0;
|
||||
short dataOffset = gsinitOffset;
|
||||
for (Objfile obj : required) {
|
||||
obj.setAreaOffset(_DATA, dataOffset);
|
||||
dataSize += obj.getAreaSize(_DATA);
|
||||
dataOffset += obj.getAreaSize(_DATA);
|
||||
}
|
||||
byte[] image = new byte[gsinitOffset];
|
||||
for (Objfile obj : required) {
|
||||
System.out.printf("Relocating: %s %s=%04X %s=%04X %s=%04X\n", obj.getFile(),
|
||||
_CODE, obj.getArea(_CODE).getOffset(),
|
||||
_GSINIT, obj.getArea(_GSINIT).getOffset(),
|
||||
_DATA, obj.getArea(_DATA).getOffset());
|
||||
obj.relocate(_CODE, image);
|
||||
obj.relocate(_GSINIT, image);
|
||||
}
|
||||
// the end of GSINIT
|
||||
image[image.length - 1] = (byte) 0xc9;
|
||||
|
||||
System.out.println("_CODE:" + Integer.toHexString(codeSize));
|
||||
System.out.println("_GSINIT:" + Integer.toHexString(gsinitSize));
|
||||
System.out.println("_DATA:" + Integer.toHexString(dataSize));
|
||||
dump(image, dataOffset);
|
||||
out(new File("tmp.out"), image, dataOffset);
|
||||
}
|
||||
|
||||
private void dump(byte[] image, int size) {
|
||||
int address = 0;
|
||||
System.out.printf("size:%04X", size);
|
||||
while (address < image.length) {
|
||||
if (address % 16 == 0) {
|
||||
System.out.printf("\n%04X:", address);
|
||||
}
|
||||
System.out.printf("%02x ", image[address++]);
|
||||
}
|
||||
System.out.println();
|
||||
System.out.println("Relocations:" + _relocations.size());
|
||||
for (RelocationInformation reloc : _relocations) {
|
||||
System.out.println(reloc);
|
||||
}
|
||||
}
|
||||
|
||||
private void out(File file, byte[] image, int size) throws IOException {
|
||||
FileOutputStream stream = new FileOutputStream(file);
|
||||
stream.write(size & 0xff);
|
||||
stream.write(size >> 8);
|
||||
stream.write(image);
|
||||
stream.write(_relocations.size() & 0xff);
|
||||
stream.write(_relocations.size() >> 8);
|
||||
for (RelocationInformation reloc : _relocations) {
|
||||
reloc.write(stream);
|
||||
}
|
||||
stream.close();
|
||||
}
|
||||
|
||||
private void make(List<Objfile> objects, Objfile obj) {
|
||||
if (objects.contains(obj)) {
|
||||
return;
|
||||
}
|
||||
objects.add(obj);
|
||||
Set<File> required = obj.getRequiredFiles();
|
||||
for (File require : required) {
|
||||
make(objects, _objfiles.get(require));
|
||||
}
|
||||
}
|
||||
|
||||
private void loadLibfile(String filename) throws IOException {
|
||||
File file = new File(filename);
|
||||
File dir = file.getParentFile();
|
||||
BufferedReader isr = new BufferedReader(new FileReader(file));
|
||||
while (true) {
|
||||
String line = isr.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
File objfile = new File(dir, line);
|
||||
Objfile object = new Objfile(this, objfile);
|
||||
_objfiles.put(objfile, object);
|
||||
object.analyze();
|
||||
}
|
||||
}
|
||||
|
||||
public void addSymbol(String name, Symbol symbol) {
|
||||
if (!_symbols.containsKey(name)) {
|
||||
_symbols.put(name, symbol);
|
||||
} else if (_symbols.get(name).getArea() != null) {
|
||||
System.out.println("Warning: duplicate symbol:" + name);
|
||||
}
|
||||
}
|
||||
|
||||
public void addRelocation(RelocationInformation info) {
|
||||
_relocations.add(info);
|
||||
}
|
||||
|
||||
public Symbol getSymbol(String name) {
|
||||
return _symbols.get(name);
|
||||
}
|
||||
|
||||
private void loadSymfile(String filename) throws IOException {
|
||||
File file = new File(filename);
|
||||
BufferedReader isr = new BufferedReader(new FileReader(file));
|
||||
while (true) {
|
||||
String line = isr.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
if (line.startsWith(";")) {
|
||||
// comment
|
||||
continue;
|
||||
}
|
||||
Matcher m = SYMLINE.matcher(line);
|
||||
if (!m.find()) {
|
||||
continue;
|
||||
}
|
||||
Symbol symbol = new Symbol(file, Integer.parseInt(m.group(1), 16));
|
||||
_symbols.put(m.group(2), symbol);
|
||||
}
|
||||
isr.close();
|
||||
}
|
||||
}
|
175
tools/z80/java/src/org/markn/contiki/z80/linker/Objfile.java
Normal file
175
tools/z80/java/src/org/markn/contiki/z80/linker/Objfile.java
Normal file
|
@ -0,0 +1,175 @@
|
|||
package org.markn.contiki.z80.linker;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author markn
|
||||
*
|
||||
*/
|
||||
public class Objfile {
|
||||
private static final Pattern REFLINE = Pattern.compile("^S\\s(\\w+)\\sRef([\\dA-F]{4})");
|
||||
private static final Pattern DEFLINE = Pattern.compile("^S\\s(\\w+)\\sDef([\\dA-F]{4})");
|
||||
private static final Pattern AREALINE = Pattern.compile("^A\\s(\\w+)\\ssize\\s([\\dA-F]+)");
|
||||
|
||||
/**
|
||||
* Parent object.
|
||||
*/
|
||||
private Linker _linker;
|
||||
|
||||
/**
|
||||
* A file that this object indicates.
|
||||
*/
|
||||
private File _file;
|
||||
|
||||
/**
|
||||
* References to be imported.
|
||||
*/
|
||||
private List<String> _refs;
|
||||
|
||||
/**
|
||||
* Area name and its size.
|
||||
*/
|
||||
private Map<String, Area> _areas;
|
||||
|
||||
/**
|
||||
* @param linker
|
||||
* @param file
|
||||
*/
|
||||
public Objfile(Linker linker, File file) {
|
||||
_linker = linker;
|
||||
_file = file;
|
||||
_refs = new ArrayList<String>();
|
||||
_areas = new HashMap<String, Area>();
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return _file;
|
||||
}
|
||||
|
||||
public Set<File> getRequiredFiles() {
|
||||
Set<File> files = new HashSet<File>();
|
||||
for (String ref : _refs) {
|
||||
if (_linker.getSymbol(ref).isAbsolute()) {
|
||||
// no need to link
|
||||
continue;
|
||||
}
|
||||
Symbol symbol = _linker.getSymbol(ref);
|
||||
if (symbol != null) {
|
||||
files.add(symbol.getFile());
|
||||
} else {
|
||||
System.out.println("undefined symbol:" + ref);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public Linker getLinker() {
|
||||
return _linker;
|
||||
}
|
||||
|
||||
public Area getArea(String name) {
|
||||
return _areas.get(name);
|
||||
}
|
||||
|
||||
public int getAreaSize(String name) {
|
||||
Area area = _areas.get(name);
|
||||
if (area != null) {
|
||||
return area.getSize();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAreaOffset(String name, short offset) {
|
||||
Area area = _areas.get(name);
|
||||
if (area != null) {
|
||||
area.setOffset(offset);
|
||||
}
|
||||
}
|
||||
|
||||
public void analyze() throws IOException {
|
||||
System.out.println("analyzing:" + _file);
|
||||
int areaindex = 0;
|
||||
BufferedReader isr = new BufferedReader(new FileReader(_file));
|
||||
String tline = null;
|
||||
Area area = null;
|
||||
while (true) {
|
||||
String line = isr.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
Matcher m = AREALINE.matcher(line);
|
||||
if (m.find()) {
|
||||
String areaname = m.group(1);
|
||||
area = new Area(areaindex, areaname, Integer.parseInt(m.group(2), 16));
|
||||
_areas.put(areaname, area);
|
||||
areaindex++;
|
||||
continue;
|
||||
}
|
||||
m = REFLINE.matcher(line);
|
||||
if (m.find()) {
|
||||
_refs.add(m.group(1));
|
||||
continue;
|
||||
}
|
||||
m = DEFLINE.matcher(line);
|
||||
if (m.find()) {
|
||||
String symbolname = m.group(1);
|
||||
int address = Integer.parseInt(m.group(2), 16);
|
||||
Symbol symbol = new Symbol(_file, area, (short) address);
|
||||
_linker.addSymbol(symbolname, symbol);
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("T")) {
|
||||
// process T line
|
||||
tline = line;
|
||||
}
|
||||
if (line.startsWith("R")) {
|
||||
// process R line
|
||||
if (tline == null) {
|
||||
System.out.println("wrong format as object file:" + _file);
|
||||
continue;
|
||||
}
|
||||
new Line(this, tline, line);
|
||||
tline = null;
|
||||
}
|
||||
}
|
||||
isr.close();
|
||||
}
|
||||
|
||||
public Area getArea(int index) {
|
||||
for (Area area : _areas.values()) {
|
||||
if (area.getIndex() == index) {
|
||||
return area;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Symbol getSymbol(int index) {
|
||||
String name = _refs.get(index);
|
||||
return _linker.getSymbol(name);
|
||||
}
|
||||
|
||||
public void relocate(String areaname, byte[] image) {
|
||||
Area area = _areas.get(areaname);
|
||||
if (area != null) {
|
||||
area.relocate(this, image);
|
||||
return;
|
||||
}
|
||||
System.out.println("no such area:" + areaname + " on " + _file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package org.markn.contiki.z80.linker;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class RelocationInformation {
|
||||
private byte _mode;
|
||||
private int _address;
|
||||
private int _data;
|
||||
public byte getMode() {
|
||||
return _mode;
|
||||
}
|
||||
public void setMode(byte mode) {
|
||||
this._mode = mode;
|
||||
}
|
||||
public int getAddress() {
|
||||
return _address;
|
||||
}
|
||||
public void setAddress(int address) {
|
||||
_address = address;
|
||||
}
|
||||
public int getData() {
|
||||
return _data;
|
||||
}
|
||||
public void setData(int data) {
|
||||
_data = data;
|
||||
}
|
||||
public void write(OutputStream stream) throws IOException {
|
||||
stream.write(_mode);
|
||||
stream.write(_address & 0xff);
|
||||
stream.write(_address >> 8);
|
||||
stream.write(_data & 0xff);
|
||||
stream.write(_data >> 8);
|
||||
}
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append((_mode & 0x80) > 0 ? 'E' : 'I');
|
||||
if ((_mode & 0x60) == 0x60) {
|
||||
buf.append("MB");
|
||||
} else if ((_mode & 0x20) > 0) {
|
||||
buf.append("LB");
|
||||
} else {
|
||||
buf.append("_W");
|
||||
}
|
||||
// buf.append((_mode & 0x60) > 0 ? 'M' : 'L');
|
||||
// buf.append((_mode & 0x20) > 0 ? 'B' : 'W');
|
||||
buf.append(String.format(":%04X:%04X", _address, _data));
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
52
tools/z80/java/src/org/markn/contiki/z80/linker/Symbol.java
Normal file
52
tools/z80/java/src/org/markn/contiki/z80/linker/Symbol.java
Normal file
|
@ -0,0 +1,52 @@
|
|||
package org.markn.contiki.z80.linker;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Symbol {
|
||||
private File _file;
|
||||
private Area _area;
|
||||
private int _offset;
|
||||
public Symbol(File file, int offset) {
|
||||
this(file, null, offset);
|
||||
}
|
||||
public Symbol(File file, Area area, int offset) {
|
||||
this._file = file;
|
||||
this._area = area;
|
||||
this._offset = offset;
|
||||
}
|
||||
public File getFile() {
|
||||
return _file;
|
||||
}
|
||||
public Area getArea() {
|
||||
return _area;
|
||||
}
|
||||
public boolean isAbsolute() {
|
||||
return _area == null;
|
||||
}
|
||||
public int getOffset() {
|
||||
return _offset;
|
||||
}
|
||||
public int calcOffset() {
|
||||
if (isAbsolute()) {
|
||||
return _offset;
|
||||
} else {
|
||||
return _offset + _area.getOffset();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer(120);
|
||||
buf.append(_file.toString());
|
||||
buf.append(':');
|
||||
if (_area != null) {
|
||||
buf.append(_area);
|
||||
} else {
|
||||
buf.append("Absolute");
|
||||
}
|
||||
buf.append(':');
|
||||
buf.append(Integer.toHexString(_offset));
|
||||
return buf.toString();
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue