src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File
*** old/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java Tue Aug 22 11:46:28 2017
--- new/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java Tue Aug 22 11:46:28 2017
*** 22,94 ****
--- 22,84 ----
*/
package jdk.tools.jaotc.binformat.elf;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import jdk.tools.jaotc.binformat.Container;
import jdk.tools.jaotc.binformat.BinaryContainer;
import jdk.tools.jaotc.binformat.ByteContainer;
import jdk.tools.jaotc.binformat.CodeContainer;
import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
import jdk.tools.jaotc.binformat.Relocation;
import jdk.tools.jaotc.binformat.Relocation.RelocType;
import jdk.tools.jaotc.binformat.Symbol;
import jdk.tools.jaotc.binformat.NativeSymbol;
import jdk.tools.jaotc.binformat.Symbol.Binding;
import jdk.tools.jaotc.binformat.Symbol.Kind;
import jdk.tools.jaotc.binformat.elf.Elf;
import jdk.tools.jaotc.binformat.elf.ElfSymbol;
import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr;
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rel;
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
public class JELFRelocObject {
private final BinaryContainer binContainer;
private final ElfContainer elfContainer;
private final int segmentSize;
- public JELFRelocObject(BinaryContainer binContainer, String outputFileName, String aotVersion) {
this.binContainer = binContainer;
- this.elfContainer = new ElfContainer(outputFileName, aotVersion);
this.segmentSize = binContainer.getCodeSegmentSize();
}
! private static ElfSection createByteSection(ArrayList<ElfSection> sections,
String sectName,
! byte [] scnData,
! byte[] scnData,
boolean hasRelocs,
int align,
int scnFlags,
int scnType) {
! ElfSection sect = new ElfSection(sectName, scnData, scnFlags, scnType,
scnData,
scnFlags,
scnType,
hasRelocs,
align,
sections.size());
+ hasRelocs, align, sections.size());
// Add this section to our list
sections.add(sect);
return (sect);
}
! private void createByteSection(ArrayList<ElfSection> sections,
ByteContainer c, int scnFlags) {
ElfSection sect;
boolean hasRelocs = c.hasRelocations();
byte[] scnData = c.getByteArray();
*** 110,128 ****
--- 100,118 ----
scnData, hasRelocs, segmentSize,
scnFlags, scnType);
c.setSectionId(sect.getSectionId());
}
! private void createCodeSection(ArrayList<ElfSection> sections, CodeContainer c) {
createByteSection(sections, c, Elf64_Shdr.SHF_ALLOC | Elf64_Shdr.SHF_EXECINSTR);
}
! private void createReadOnlySection(ArrayList<ElfSection> sections, ReadOnlyDataContainer c) {
createByteSection(sections, c, Elf64_Shdr.SHF_ALLOC);
}
! private void createReadWriteSection(ArrayList<ElfSection> sections, ByteContainer c) {
createByteSection(sections, c, Elf64_Shdr.SHF_ALLOC | Elf64_Shdr.SHF_WRITE);
}
/**
* Create an ELF relocatable object
*** 133,233 ****
--- 123,209 ----
*/
public void createELFRelocObject(Map<Symbol, List<Relocation>> relocationTable, Collection<Symbol> symbols) throws IOException {
// Allocate ELF Header
ElfHeader eh = new ElfHeader();
- ArrayList<ElfSection> sections = new ArrayList<ElfSection>();
// Create the null section
createByteSection(sections, null, null, false, 1, 0, 0);
// Create text section
createCodeSection(sections, binContainer.getCodeContainer());
createReadOnlySection(sections, binContainer.getMetaspaceNamesContainer());
createReadOnlySection(sections, binContainer.getKlassesOffsetsContainer());
createReadOnlySection(sections, binContainer.getMethodsOffsetsContainer());
createReadOnlySection(sections, binContainer.getKlassesDependenciesContainer());
! createReadWriteSection(sections, binContainer.getMetaspaceGotContainer());
createReadWriteSection(sections, binContainer.getMetadataGotContainer());
createReadWriteSection(sections, binContainer.getMethodStateContainer());
createReadWriteSection(sections, binContainer.getOopGotContainer());
createReadWriteSection(sections, binContainer.getMethodMetadataContainer());
! createReadOnlySection(sections, binContainer.getMethodMetadataContainer());
createReadOnlySection(sections, binContainer.getStubsOffsetsContainer());
createReadOnlySection(sections, binContainer.getHeaderContainer().getContainer());
createReadOnlySection(sections, binContainer.getCodeSegmentsContainer());
createReadOnlySection(sections, binContainer.getConstantDataContainer());
createReadOnlySection(sections, binContainer.getConfigContainer());
! // createExternalLinkage();
! createCodeSection(sections, binContainer.getExtLinkageContainer());
+ createReadWriteSection(sections, binContainer.getKlassesGotContainer());
! createReadWriteSection(sections, binContainer.getCountersGotContainer());
+ createReadWriteSection(sections, binContainer.getMetadataGotContainer());
! createReadWriteSection(sections, binContainer.getOopGotContainer());
+ createReadWriteSection(sections, binContainer.getMethodStateContainer());
createReadWriteSection(sections, binContainer.getExtLinkageGOTContainer());
// Get ELF symbol data from BinaryContainer object's symbol tables
- ElfSymtab symtab = createELFSymbolTables(sections, symbols);
// Create string table section and symbol table sections in
// that order since symtab section needs to set the index of
// strtab in sh_link field
! ElfSection strTabSection = createByteSection(sections, ".strtab",
".strtab",
symtab.getStrtabArray(),
! false, 1, 0,
1,
0,
Elf64_Shdr.SHT_STRTAB);
// Now create .symtab section with the symtab data constructed.
// On Linux, sh_link of symtab contains the index of string table
// its symbols reference and sh_info contains the index of first
// non-local symbol
! ElfSection symTabSection = createByteSection(sections, ".symtab",
".symtab",
symtab.getSymtabArray(),
! false, 8, 0,
8,
0,
Elf64_Shdr.SHT_SYMTAB);
symTabSection.setLink(strTabSection.getSectionId());
symTabSection.setInfo(symtab.getNumLocalSyms());
! ElfRelocTable elfRelocTable = createElfRelocTable(sections, relocationTable);
relocationTable);
createElfRelocSections(sections, elfRelocTable, symTabSection.getSectionId());
// Now, finally, after creating all sections, create shstrtab section
! ElfSection shStrTabSection = createByteSection(sections, ".shstrtab",
! ".shstrtab",
null,
false,
1,
0,
! null, false, 1, 0,
Elf64_Shdr.SHT_STRTAB);
eh.setSectionStrNdx(shStrTabSection.getSectionId());
// Update all section offsets and the Elf header section offset
// Write the Header followed by the contents of each section
// and then the section structures (section table).
int file_offset = Elf64_Ehdr.totalsize;
// and round it up
! file_offset = (file_offset + (sections.get(1).getDataAlign() - 1)) &
! ~((sections.get(1).getDataAlign() - 1));
// Calc file offsets for section data skipping null section
for (int i = 1; i < sections.size(); i++) {
ElfSection sect = sections.get(i);
! file_offset = (file_offset + (sect.getDataAlign() - 1)) &
! ~((sect.getDataAlign()-1));
! ~((sect.getDataAlign() - 1));
sect.setOffset(file_offset);
file_offset += sect.getSize();
}
// Align the section table
! file_offset = (file_offset + (ElfSection.getShdrAlign() - 1)) &
! ~((ElfSection.getShdrAlign() - 1));
// Update the Elf Header with the offset of the first Elf64_Shdr
// and the number of sections.
eh.setSectionOff(file_offset);
eh.setSectionNum(sections.size());
*** 247,274 ****
--- 223,251 ----
elfContainer.writeBytes(sect.getArray(), ElfSection.getShdrAlign());
}
elfContainer.close();
}
+
/**
! * Construct ELF symbol data from BinaryContainer object's symbol tables. Both dynamic ELF symbol
- * symbol table and ELF symbol table are created from BinaryContainer's symbol info.
*
* @param symbols
*/
! private ElfSymtab createELFSymbolTables(ArrayList<ElfSection> sections, Collection<Symbol> symbols) {
! private static ElfSymtab createELFSymbolTables(Collection<Symbol> symbols) {
ElfSymtab symtab = new ElfSymtab();
// First, create the initial null symbol. This is a local symbol.
! symtab.addSymbolEntry("", (byte) 0, (byte) 0, Elf64_Shdr.SHN_UNDEF, 0, 0);
// Now create ELF symbol entries for all symbols.
for (Symbol symbol : symbols) {
// Get the index of section this symbol is defined in.
int secHdrIndex = symbol.getSection().getSectionId();
! ElfSymbol elfSymbol = symtab.addSymbolEntry(symbol.getName(), getELFTypeOf(symbol), getELFBindOf(symbol), (byte) secHdrIndex, symbol.getOffset(), symbol.getSize());
- symbol.setNativeSymbol((NativeSymbol)elfSymbol);
}
return (symtab);
}
private static byte getELFTypeOf(Symbol sym) {
*** 298,309 ****
--- 275,285 ----
private ElfRelocTable createElfRelocTable(ArrayList<ElfSection> sections,
Map<Symbol, List<Relocation>> relocationTable) {
ElfRelocTable elfRelocTable = new ElfRelocTable(sections.size());
/*
! * For each of the symbols with associated relocation records, create a Elf relocation entry.
* entry.
*/
for (Map.Entry<Symbol, List<Relocation>> entry : relocationTable.entrySet()) {
List<Relocation> relocs = entry.getValue();
Symbol symbol = entry.getKey();
*** 317,389 ****
--- 293,335 ----
}
return (elfRelocTable);
}
! private static void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) {
RelocType relocType = reloc.getType();
int elfRelocType = getELFRelocationType(relocType);
! ElfSymbol sym = (ElfSymbol) symbol.getNativeSymbol();
int symno = sym.getIndex();
int sectindex = reloc.getSection().getSectionId();
int offset = reloc.getOffset();
int addend = 0;
switch (relocType) {
case FOREIGN_CALL_DIRECT:
case JAVA_CALL_DIRECT:
case STUB_CALL_DIRECT:
case FOREIGN_CALL_INDIRECT_GOT: {
// Create relocation entry
// System.out.println("getELFRelocationType: PLT relocation type using X86_64_RELOC_BRANCH");
addend = -4; // Size in bytes of the patch location
// Relocation should be applied at the location after call operand
offset = offset + reloc.getSize() + addend;
break;
}
case FOREIGN_CALL_DIRECT_FAR: {
// Create relocation entry
addend = -8; // Size in bytes of the patch location
// Relocation should be applied at the location after call operand
// 10 = 2 (jmp [r]) + 8 (imm64)
offset = offset + reloc.getSize() + addend - 2;
break;
}
case FOREIGN_CALL_INDIRECT:
case JAVA_CALL_INDIRECT:
case STUB_CALL_INDIRECT: {
// Do nothing.
return;
}
case EXTERNAL_DATA_REFERENCE_FAR: {
// Create relocation entry
addend = -4; // Size of 32-bit address of the GOT
/*
* Relocation should be applied before the test instruction to the move instruction.
* offset points to the test instruction after the instruction that loads
* the address of polling page. So set the offset appropriately.
*/
offset = offset + addend;
break;
}
case METASPACE_GOT_REFERENCE:
! case EXTERNAL_PLT_TO_GOT: {
case STATIC_STUB_TO_STATIC_METHOD:
case STATIC_STUB_TO_HOTSPOT_LINKAGE_GOT: {
addend = -4; // Size of 32-bit address of the GOT
/*
! * Relocation should be applied before the test instruction to the move instruction.
* the move instruction. reloc.getOffset() points to the
* test instruction after the instruction that loads the
* address of polling page. So set the offset appropriately.
+ * reloc.getOffset() points to the test instruction after the instruction that loads the address of
+ * polling page. So set the offset appropriately.
*/
offset = offset + addend;
break;
}
! case EXTERNAL_GOT_TO_PLT: {
case LOADTIME_ADDRESS: {
// this is load time relocations
break;
}
default:
throw new InternalError("Unhandled relocation type: " + relocType);
*** 394,424 ****
--- 340,360 ----
private static int getELFRelocationType(RelocType relocType) {
int elfRelocType = 0; // R_<ARCH>_NONE if #define'd to 0 for all values of ARCH
switch (ElfTargetInfo.getElfArch()) {
case Elf64_Ehdr.EM_X86_64:
// Return R_X86_64_* entries based on relocType
! if (relocType == RelocType.FOREIGN_CALL_DIRECT ||
relocType == RelocType.JAVA_CALL_DIRECT ||
! if (relocType == RelocType.JAVA_CALL_DIRECT ||
relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
elfRelocType = Elf64_Rela.R_X86_64_PLT32;
} else if (relocType == RelocType.STUB_CALL_DIRECT) {
elfRelocType = Elf64_Rela.R_X86_64_PC32;
! } else if (relocType == RelocType.FOREIGN_CALL_DIRECT_FAR) {
elfRelocType = Elf64_Rela.R_X86_64_64;
} else if (relocType == RelocType.FOREIGN_CALL_INDIRECT ||
relocType == RelocType.JAVA_CALL_INDIRECT ||
relocType == RelocType.STUB_CALL_INDIRECT) {
! } else if (relocType == RelocType.JAVA_CALL_INDIRECT) {
elfRelocType = Elf64_Rela.R_X86_64_NONE;
} else if ((relocType == RelocType.EXTERNAL_DATA_REFERENCE_FAR)) {
elfRelocType = Elf64_Rela.R_X86_64_GOTPCREL;
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
! relocType == RelocType.EXTERNAL_PLT_TO_GOT ||
relocType == RelocType.STATIC_STUB_TO_STATIC_METHOD ||
relocType == RelocType.STATIC_STUB_TO_HOTSPOT_LINKAGE_GOT) {
! relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
elfRelocType = Elf64_Rela.R_X86_64_PC32;
! } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT ||
relocType == RelocType.LOADTIME_ADDRESS) {
! } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
elfRelocType = Elf64_Rela.R_X86_64_64;
} else {
assert false : "Unhandled relocation type: " + relocType;
}
break;
*** 426,453 ****
--- 362,385 ----
System.out.println("Relocation Type mapping: Unhandled architecture");
}
return elfRelocType;
}
! private static void createElfRelocSections(ArrayList<ElfSection> sections,
ElfRelocTable elfRelocTable,
int symtabsectidx) {
// Grab count before we create new sections
int count = sections.size();
for (int i = 0; i < count; i++) {
if (elfRelocTable.getNumRelocs(i) > 0) {
ElfSection sect = sections.get(i);
String relname = ".rela" + sect.getName();
! ElfSection relocSection = createByteSection(sections, relname,
relname,
elfRelocTable.getRelocData(i),
false,
8,
0,
Elf64_Shdr.SHT_RELA);
+ false, 8, 0, Elf64_Shdr.SHT_RELA);
relocSection.setLink(symtabsectidx);
relocSection.setInfo(sect.getSectionId());
}
}
}
src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File