elflinker.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 121 行
JAVA
121 行
//
// ElfLinker.java
//
package org.jnode.linker;
import java.io.IOException;
import org.jnode.assembler.Label;
import org.jnode.assembler.x86.X86Stream;
import org.jnode.build.BuildException;
/**
* Build the boot image from an assembler compiled bootstrap (in ELF format)
* combined with the precompiled Java classes.
**/
public class ElfLinker {
private X86Stream os;
private int baseAddr;
public ElfLinker(X86Stream os) {
this.os = os;
baseAddr = (int)os.getBaseAddr();
}
/**
* Load an ELF object file with a given name and link it into the native
* stream.
*/
public void loadElfObject(String name) throws BuildException {
Elf elf;
try {
elf = Elf.newFromFile(name);
loadElfObject(elf);
} catch (IOException ex) {
throw new BuildException(ex);
}
}
/**
* Load an ELF object file with a given name and link it into the native
* stream.
*/
public void loadElfObject(Elf elf) throws BuildException {
if (!elf.isRel()) {
throw new BuildException("Elf object is not relocatable");
}
Section text = elf.getSectionByName(".text");
if (text == null) {
throw new BuildException(".text section not found");
}
// Write the code
int start = os.getLength();
byte[] tdata = text.getBody();
os.write(tdata, 0, tdata.length);
// Add all resolved symbols
int cnt = elf.getNoSymbols();
for (int i = 1; i < cnt; i++) {
Symbol sym = elf.getSymbol(i);
Section sec = sym.getSection();
if (sec == text) {
X86Stream.X86ObjectRef ref = (X86Stream.X86ObjectRef)os.getObjectRef(new Label(sym.getName()));
ref.setPublic();
if (!sym.isUndef()) {
//System.out.println("Defined symbol at " + sym.getValue() + " [" + sym.getName() + "]");
ref.setOffset(sym.getValue() + start);
} else {
System.out.println("Undefined symbol: " + sym.getName());
}
} else if ((sec != null) && !sym.isUndef()){
System.out.println("Symbol '"+ sym.getName() + "' refers to unknown section '" + sec.getName() + "'");
}
}
// Add all relocation items
Section rels = elf.getSectionByName(".rel.text");
if (rels != null) {
cnt = rels.getNoRelocs();
for (int i = 0; i < cnt; i++) {
Reloc r = rels.getReloc(i);
if (!(r.isPcRel() || r.isAbs())) {
throw new BuildException("Only PC relative and ABS relocations are supported");
}
final int addr = r.getAddress() + start;
if (r.isAbs() && (r.getSymbol().getName().length() == 0)) {
//System.out.print("Abs reloc at "+ addr + "=" + os.get32(addr));
os.set32(addr, os.get32(addr) + start + baseAddr);
//System.out.println(" base=" + baseAddr + " start=" + start);
} else {
X86Stream.X86ObjectRef ref = (X86Stream.X86ObjectRef)os.getObjectRef(new Label(r.getSymbol().getName()));
if (ref.isResolved()) {
//System.out.println("Resolved reloc " + ref.getObject());
if (r.isPcRel()) {
os.set32(addr, ref.getOffset() - (addr + 4));
} else if (r.isAbs()) {
os.set32(addr, ref.getOffset() + baseAddr);
} else {
throw new BuildException("Unknown relocation type " + r);
}
} else {
//System.out.println("Unresolved reloc " + ref.getObject() + " at address " + r.getAddress());
if (r.isAbs()) {
os.set32(addr, -baseAddr);
ref.addUnresolvedLink(addr);
} else if (r.isPcRel()) {
ref.addUnresolvedLink(addr);
} else {
throw new BuildException("Unknown relocation type " + r);
}
}
}
}
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?