* 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");
}
final Section text = elf.getSectionByName(".text");
if (text == null) {
throw new BuildException(".text section not found");
}
// Write the code
start = os.getLength();
final byte[] tdata = text.getBody();
os.write(tdata, 0, tdata.length);
// Add all resolved symbols
final int symCnt = elf.getNoSymbols();
for (int i = 1; i < symCnt; i++) {
final Symbol sym = elf.getSymbol(i);
final Section sec = sym.getSection();
if (sec == text) {
// System.out.println(sym);
X86BinaryAssembler.X86ObjectRef ref = (X86BinaryAssembler.X86ObjectRef) os
.getObjectRef(new Label(sym.getName()));
ref.setPublic();
if (!sym.isUndef()) {
// System.out.println("Defined symbol at " + sym.getValue()
// + " [" + sym.getName() + "]");
ref.setOffset((int) 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) {
rels = elf.getSectionByName(".rela.text");
}
if (rels != null) {
final int relocCnt = rels.getNoRelocs();
for (int i = 0; i < relocCnt; i++) {
try {
final Reloc r = rels.getReloc(i);
final String symName = r.getSymbol().getName();
final boolean hasSymName = (symName.length() > 0);
final boolean hasAddEnd = r.hasAddEnd();
final long addr = r.getAddress() + start;
final long addend = r.getAddEnd();
final Reloc.Type relocType = r.getRelocType();
if ((relocType == Reloc.R_386_32) && !hasAddEnd) {
resolve_R386_32(addr, symName, hasSymName);
} else if ((relocType == Reloc.R_386_PC32) && !hasAddEnd) {
resolve_R386_PC32(addr, symName, hasSymName);
} else if ((relocType == Reloc.R_X86_64_32) && hasAddEnd) {
resolve_R_X86_64_32(addr, addend, symName, hasSymName);
} else if ((relocType == Reloc.R_X86_64_64) && hasAddEnd) {
resolve_R_X86_64_64(addr, addend, symName, hasSymName);
} else {
throw new BuildException("Unknown relocation type "
+ relocType);
}
} catch (UnresolvedObjectRefException ex) {
throw new BuildException(ex);
}
}
}
}