--- old/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java 2017-02-08 13:34:53.206942576 -0500 +++ new/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java 2017-02-08 13:34:51.134823055 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ 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; @@ -37,36 +38,60 @@ 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.jnilibelf.ELFContainer; -import jdk.tools.jaotc.jnilibelf.ELFSymbol; -import jdk.tools.jaotc.jnilibelf.JNIELFContainer; -import jdk.tools.jaotc.jnilibelf.JNIELFRelocation; -import jdk.tools.jaotc.jnilibelf.JNIELFTargetInfo; -import jdk.tools.jaotc.jnilibelf.JNILibELFAPI.ELF; -import jdk.tools.jaotc.jnilibelf.JNILibELFAPI.LibELF.Elf_Cmd; -import jdk.tools.jaotc.jnilibelf.JNILibELFAPI.LibELF.Elf_Type; -import jdk.tools.jaotc.jnilibelf.Pointer; + +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 JNIELFContainer elfContainer; + private final ElfContainer elfContainer; private final int segmentSize; public JELFRelocObject(BinaryContainer binContainer, String outputFileName, String aotVersion) { this.binContainer = binContainer; - this.elfContainer = new JNIELFContainer(outputFileName, aotVersion); + this.elfContainer = new ElfContainer(outputFileName, aotVersion); this.segmentSize = binContainer.getCodeSegmentSize(); } - private void createByteSection(ByteContainer c, int scnFlags) { + private ElfSection createByteSection(ArrayListsections, + String sectName, + byte [] scnData, + boolean hasRelocs, + int scnFlags, + int scnType) { + + ElfSection sect = new ElfSection(sectName, + scnData, + scnFlags, + scnType, + hasRelocs, + sections.size()); + // Add this section to our list + sections.add(sect); + + return (sect); + } + + private void createByteSection(ArrayListsections, + ByteContainer c, int scnFlags) { + ElfSection sect; + boolean hasRelocs = c.hasRelocations(); byte[] scnData = c.getByteArray(); - int scnType = ELF.SHT_PROGBITS; - boolean zeros = !c.hasRelocations(); + + int scnType = Elf64_Shdr.SHT_PROGBITS; + boolean zeros = hasRelocs; if (zeros) { for (byte b : scnData) { if (b != 0) { @@ -75,30 +100,30 @@ } } if (zeros) { - scnType = ELF.SHT_NOBITS; + scnType = Elf64_Shdr.SHT_NOBITS; } } - int sectionId = elfContainer.createSection(c.getContainerName(), scnData, Elf_Type.ELF_T_BYTE, segmentSize, scnType, scnFlags, ELF.SHN_UNDEF, 0); - c.setSectionId(sectionId); - // Clear out code section data to allow for GC - c.clear(); + sect = createByteSection(sections, c.getContainerName(), + scnData, hasRelocs, + scnFlags, scnType); + c.setSectionId(sect.getSectionId()); } - private void createCodeSection(CodeContainer c) { - createByteSection(c, ELF.SHF_ALLOC | ELF.SHF_EXECINSTR); + private void createCodeSection(ArrayListsections, CodeContainer c) { + createByteSection(sections, c, Elf64_Shdr.SHF_ALLOC | Elf64_Shdr.SHF_EXECINSTR); } - private void createReadOnlySection(ReadOnlyDataContainer c) { - createByteSection(c, ELF.SHF_ALLOC); + private void createReadOnlySection(ArrayListsections, ReadOnlyDataContainer c) { + createByteSection(sections, c, Elf64_Shdr.SHF_ALLOC); } - private void createReadWriteSection(ByteContainer c) { - createByteSection(c, ELF.SHF_ALLOC | ELF.SHF_WRITE); + private void createReadWriteSection(ArrayListsections, ByteContainer c) { + createByteSection(sections, c, Elf64_Shdr.SHF_ALLOC | Elf64_Shdr.SHF_WRITE); } /** - * Create an ELF relocatable object using jdk.tools.jaotc.jnilibelf API. + * Create an ELF relocatable object * * @param relocationTable * @param symbols @@ -106,145 +131,171 @@ */ public void createELFRelocObject(Map> relocationTable, Collection symbols) throws IOException { // Allocate ELF Header - elfContainer.createELFHeader(ELF.ET_REL); + ElfHeader eh = new ElfHeader(); + + ArrayList sections = new ArrayList(); + + // Create the null section + createByteSection(sections, null, null, false, 0, 0); // Create text section - createCodeSection(binContainer.getCodeContainer()); - createReadOnlySection(binContainer.getMetaspaceNamesContainer()); - createReadOnlySection(binContainer.getKlassesOffsetsContainer()); - createReadOnlySection(binContainer.getMethodsOffsetsContainer()); - createReadOnlySection(binContainer.getKlassesDependenciesContainer()); - createReadWriteSection(binContainer.getMetaspaceGotContainer()); - createReadWriteSection(binContainer.getMetadataGotContainer()); - createReadWriteSection(binContainer.getMethodStateContainer()); - createReadWriteSection(binContainer.getOopGotContainer()); - createReadWriteSection(binContainer.getMethodMetadataContainer()); - createReadOnlySection(binContainer.getStubsOffsetsContainer()); - createReadOnlySection(binContainer.getHeaderContainer().getContainer()); - createReadOnlySection(binContainer.getCodeSegmentsContainer()); - createReadOnlySection(binContainer.getConstantDataContainer()); - createReadOnlySection(binContainer.getConfigContainer()); + 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.getStubsOffsetsContainer()); + createReadOnlySection(sections, binContainer.getHeaderContainer().getContainer()); + createReadOnlySection(sections, binContainer.getCodeSegmentsContainer()); + createReadOnlySection(sections, binContainer.getConstantDataContainer()); + createReadOnlySection(sections, binContainer.getConfigContainer()); // createExternalLinkage(); - createCodeSection(binContainer.getExtLinkageContainer()); - createReadWriteSection(binContainer.getExtLinkageGOTContainer()); + createCodeSection(sections, binContainer.getExtLinkageContainer()); + createReadWriteSection(sections, binContainer.getExtLinkageGOTContainer()); // Get ELF symbol data from BinaryContainer object's symbol tables - createELFSymbolTables(symbols); + 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 - int strTabSectionIndex = elfContainer.createSection(".strtab", elfContainer.getStrTabContent().getBytes(StandardCharsets.UTF_8), Elf_Type.ELF_T_BYTE, 1, ELF.SHT_STRTAB, 0, ELF.SHN_UNDEF, 0); + // that order since symtab section needs to set the index of + // strtab in sh_link field + ElfSection strTabSection = createByteSection(sections, + ".strtab", + symtab.getStrtabArray(), + false, + 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.getSymtabArray(), + false, + 0, + Elf64_Shdr.SHT_SYMTAB); + symTabSection.setLink(strTabSection.getSectionId()); + symTabSection.setInfo(symtab.getNumLocalSyms()); - // 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 - int scnInfo = elfContainer.getFirstNonLocalSymbolIndex(); - int symTabSectionIndex = elfContainer.createSection(".symtab", getELFSymbolTableData(), Elf_Type.ELF_T_SYM, 8, ELF.SHT_SYMTAB, ELF.SHF_ALLOC, strTabSectionIndex, scnInfo); + ElfRelocTable elfRelocTable = createElfRelocTable(sections, + relocationTable); - buildRelocations(relocationTable, symTabSectionIndex); + createElfRelocSections(sections, elfRelocTable, symTabSection.getSectionId()); // Now, finally, after creating all sections, create shstrtab section - elfContainer.createSection(".shstrtab", elfContainer.getShStrTabContent().getBytes(StandardCharsets.UTF_8), Elf_Type.ELF_T_BYTE, 1, ELF.SHT_STRTAB, 0, ELF.SHN_UNDEF, 0); - - // Run elf_update - elfContainer.elfUpdate(Elf_Cmd.ELF_C_NULL); - - // Run elfUpdate again to write it out. - elfContainer.elfUpdate(Elf_Cmd.ELF_C_WRITE); - // Finish ELF processing - elfContainer.elfEnd(); - } + ElfSection shStrTabSection = createByteSection(sections, + ".shstrtab", + null, + false, + 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.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()); + + // Write out the Header + elfContainer.writeBytes(eh.getArray()); + + // Write out each section contents skipping null section + for (int i = 1; i < sections.size(); i++) { + ElfSection sect = sections.get(i); + elfContainer.writeBytes(sect.getDataArray(), sect.getDataAlign()); + } + + // Write out the section table + for (int i = 0; i < sections.size(); i++) { + ElfSection sect = sections.get(i); + elfContainer.writeBytes(sect.getArray(), ElfSection.getShdrAlign()); + } - private void buildRelocations(Map> relocationTable, final int symTabSectionIndex) { - /* - * Create relocation sections. This needs to be done after symbol table sections were - * created since relocation entries will need indices of sections to which they apply. - */ - createELFRelocationTables(relocationTable); - createAllRelocationSections(new SymTabELFContainer(symTabSectionIndex)); + elfContainer.close(); } - /** * Construct ELF symbol data from BinaryContainer object's symbol tables. Both dynamic ELF * symbol table and ELF symbol table are created from BinaryContainer's symbol info. * * @param symbols */ - private void createELFSymbolTables(Collection symbols) { + private ElfSymtab createELFSymbolTables(ArrayList sections, Collection symbols) { + ElfSymtab symtab = new ElfSymtab(); + // First, create the initial null symbol. This is a local symbol. - elfContainer.createELFSymbolEntry("", 0, 0, ELF.SHN_UNDEF, 0, 0, true); + 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(); - boolean isLocal = (symbol.getBinding() == Binding.LOCAL); - ELFSymbol elfSymbol = elfContainer.createELFSymbolEntry(symbol.getName(), getELFTypeOf(symbol), getELFBindOf(symbol), secHdrIndex, symbol.getSize(), symbol.getOffset(), isLocal); - symbol.setElfSymbol(elfSymbol); - } - } - - /** - * Construct ELF symbol data from BinaryContainer object's symbol tables. - * - * @return a byte array containing the symbol table - */ - private byte[] getELFSymbolTableData() { - final int entrySize = JNIELFTargetInfo.sizeOfSymtabEntry(); - - // First, add all local symbols. - List localSymbols = elfContainer.getLocalSymbols(); - List globalSymbols = elfContainer.getGlobalSymbols(); - - int localSymCount = localSymbols.size(); - int globalSymCount = globalSymbols.size(); - byte[] sectionDataArray = new byte[(localSymCount + globalSymCount) * entrySize]; - - for (int i = 0; i < localSymCount; i++) { - ELFSymbol symbol = localSymbols.get(i); - Pointer address = symbol.getAddress(); - address.copyBytesTo(sectionDataArray, entrySize, i * entrySize); + ElfSymbol elfSymbol = symtab.addSymbolEntry(symbol.getName(), getELFTypeOf(symbol), getELFBindOf(symbol), (byte)secHdrIndex, symbol.getOffset(), symbol.getSize()); + symbol.setNativeSymbol((NativeSymbol)elfSymbol); } - - // Next, add all global symbols. - - for (int i = 0; i < globalSymCount; i++) { - ELFSymbol symbol = globalSymbols.get(i); - Pointer address = symbol.getAddress(); - address.copyBytesTo(sectionDataArray, entrySize, (localSymCount + i) * entrySize); - } - - return sectionDataArray; + return (symtab); } - private static int getELFTypeOf(Symbol sym) { + private static byte getELFTypeOf(Symbol sym) { Kind kind = sym.getKind(); if (kind == Symbol.Kind.NATIVE_FUNCTION || kind == Symbol.Kind.JAVA_FUNCTION) { - return ELF.STT_FUNC; + return Elf64_Sym.STT_FUNC; } else if (kind == Symbol.Kind.OBJECT) { - return ELF.STT_OBJECT; + return Elf64_Sym.STT_OBJECT; } - return ELF.STT_NOTYPE; + return Elf64_Sym.STT_NOTYPE; } - private static int getELFBindOf(Symbol sym) { + private static byte getELFBindOf(Symbol sym) { Binding binding = sym.getBinding(); if (binding == Symbol.Binding.GLOBAL) { - return ELF.STB_GLOBAL; + return Elf64_Sym.STB_GLOBAL; } - return ELF.STB_LOCAL; + return Elf64_Sym.STB_LOCAL; } /** - * Construct ELF relocation section data from BinaryContainer object's relocation tables. + * Construct a Elf relocation table from BinaryContainer object's relocation tables. * + * @param sections * @param relocationTable */ - private void createELFRelocationTables(Map> relocationTable) { + private ElfRelocTable createElfRelocTable(ArrayList sections, + Map> relocationTable) { + + ElfRelocTable elfRelocTable = new ElfRelocTable(sections.size()); /* - * For each of the symbols with associated relocation records, create an ELF relocation + * For each of the symbols with associated relocation records, create a Elf relocation * entry. */ for (Map.Entry> entry : relocationTable.entrySet()) { @@ -252,18 +303,26 @@ Symbol symbol = entry.getKey(); for (Relocation reloc : relocs) { - createRelocation(symbol, reloc); + createRelocation(symbol, reloc, elfRelocTable); } } for (Map.Entry entry : binContainer.getUniqueRelocationTable().entrySet()) { - createRelocation(entry.getKey(), entry.getValue()); + createRelocation(entry.getKey(), entry.getValue(), elfRelocTable); } + + return (elfRelocTable); } - private void createRelocation(Symbol symbol, Relocation reloc) { + private 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: @@ -271,85 +330,89 @@ case STUB_CALL_DIRECT: case FOREIGN_CALL_INDIRECT_GOT: { // Create relocation entry - int addend = -4; // Size in bytes of the patch location + // 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 - int offset = reloc.getOffset() + reloc.getSize() + addend; - elfContainer.createELFRelocationEntry(reloc.getSection(), offset, elfRelocType, addend, symbol.getElfSymbol()); + offset = offset + reloc.getSize() + addend; break; } case FOREIGN_CALL_DIRECT_FAR: { // Create relocation entry - int addend = -8; // Size in bytes of the patch location + 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) - int offset = reloc.getOffset() + reloc.getSize() + addend - 2; - elfContainer.createELFRelocationEntry(reloc.getSection(), offset, elfRelocType, addend, symbol.getElfSymbol()); + offset = offset + reloc.getSize() + addend - 2; break; } case FOREIGN_CALL_INDIRECT: case JAVA_CALL_INDIRECT: case STUB_CALL_INDIRECT: { // Do nothing. - break; + return; } case EXTERNAL_DATA_REFERENCE_FAR: { // Create relocation entry - int addend = -4; // Size of 32-bit address of the GOT + addend = -4; // Size of 32-bit address of the GOT /* * Relocation should be applied before the test instruction to the move instruction. - * reloc.getOffset() points to the test instruction after the instruction that loads + * offset points to the test instruction after the instruction that loads * the address of polling page. So set the offset appropriately. */ - int offset = reloc.getOffset() + addend; - elfContainer.createELFRelocationEntry(reloc.getSection(), offset, elfRelocType, addend, symbol.getElfSymbol()); + 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: { - int addend = -4; // Size of 32-bit address of the GOT + addend = -4; // Size of 32-bit address of the GOT /* - * Relocation should be applied before the test instruction to 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. + * Relocation should be applied before the test instruction to + * 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. */ - int offset = reloc.getOffset() + addend; - elfContainer.createELFRelocationEntry(reloc.getSection(), offset, elfRelocType, addend, symbol.getElfSymbol()); + offset = offset + addend; break; } case EXTERNAL_GOT_TO_PLT: case LOADTIME_ADDRESS: { // this is load time relocations - elfContainer.createELFRelocationEntry(reloc.getSection(), reloc.getOffset(), elfRelocType, 0, symbol.getElfSymbol()); break; } default: throw new InternalError("Unhandled relocation type: " + relocType); } + elfRelocTable.createRelocationEntry(sectindex, offset, symno, elfRelocType, addend); } - // TODO: Populate the mapping of RelocType to ELF relocation types private static int getELFRelocationType(RelocType relocType) { int elfRelocType = 0; // R__NONE if #define'd to 0 for all values of ARCH - switch (JNIELFTargetInfo.getELFArch()) { - case ELF.EM_X64_64: + 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 || relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) { - elfRelocType = JNIELFRelocation.X86_64.R_X86_64_PLT32; + if (relocType == RelocType.FOREIGN_CALL_DIRECT || + 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 = JNIELFRelocation.X86_64.R_X86_64_PC32; + elfRelocType = Elf64_Rela.R_X86_64_PC32; } else if (relocType == RelocType.FOREIGN_CALL_DIRECT_FAR) { - elfRelocType = JNIELFRelocation.X86_64.R_X86_64_64; - } else if (relocType == RelocType.FOREIGN_CALL_INDIRECT || relocType == RelocType.JAVA_CALL_INDIRECT || relocType == RelocType.STUB_CALL_INDIRECT) { - elfRelocType = JNIELFRelocation.X86_64.R_X86_64_NONE; + elfRelocType = Elf64_Rela.R_X86_64_64; + } else if (relocType == RelocType.FOREIGN_CALL_INDIRECT || + relocType == RelocType.JAVA_CALL_INDIRECT || + relocType == RelocType.STUB_CALL_INDIRECT) { + elfRelocType = Elf64_Rela.R_X86_64_NONE; } else if ((relocType == RelocType.EXTERNAL_DATA_REFERENCE_FAR)) { - elfRelocType = JNIELFRelocation.X86_64.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) { - elfRelocType = JNIELFRelocation.X86_64.R_X86_64_PC32; - } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT || relocType == RelocType.LOADTIME_ADDRESS) { - elfRelocType = JNIELFRelocation.X86_64.R_X86_64_64; + 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) { + elfRelocType = Elf64_Rela.R_X86_64_PC32; + } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT || + relocType == RelocType.LOADTIME_ADDRESS) { + elfRelocType = Elf64_Rela.R_X86_64_64; } else { assert false : "Unhandled relocation type: " + relocType; } @@ -360,61 +423,26 @@ return elfRelocType; } - private void createAllRelocationSections(ELFContainer symtab) { - for (Map.Entry> entry : elfContainer.getRelocTables().entrySet()) { - createRelocationSection(entry.getKey(), entry.getValue(), symtab); - } - } - - private void createRelocationSection(ELFContainer container, ArrayList relocations, ELFContainer symtab) { - String secName = container.getContainerName(); - int entrySize = JNIELFTargetInfo.sizeOfRelocEntry(); - int numEntries = relocations.size(); - byte[] sectionDataBytes = new byte[numEntries * entrySize]; - - for (int index = 0; index < relocations.size(); index++) { - Pointer entry = relocations.get(index); - entry.copyBytesTo(sectionDataBytes, entrySize, index * entrySize); - } - String fullSecName; - // If relocDat is non-null create section - if (sectionDataBytes.length > 0) { - int scnType; - Elf_Type dataType; - if (JNIELFTargetInfo.createReloca() == 0) { - scnType = ELF.SHT_REL; - dataType = Elf_Type.ELF_T_REL; - fullSecName = ".rel" + secName; - } else { - scnType = ELF.SHT_RELA; - dataType = Elf_Type.ELF_T_RELA; - fullSecName = ".rela" + secName; + private void createElfRelocSections(ArrayList 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, + elfRelocTable.getRelocData(i), + false, + 0, + Elf64_Shdr.SHT_RELA); + relocSection.setLink(symtabsectidx); + relocSection.setInfo(sect.getSectionId()); } - // assert compareBytes(relocData.toByteArray(), sectionDataBytes) : "******* Bad array - // copy"; - // sh_link holds the index of section header of symbol table associated with this - // relocation table. - // sh_info holds the index of section header to which this relocation table applies - // to. - elfContainer.createSection(fullSecName, sectionDataBytes, dataType, 8, scnType, ELF.SHF_ALLOC, symtab.getSectionId(), container.getSectionId()); - } - } - - private static class SymTabELFContainer implements ELFContainer { - private final int symTabSectionIndex; - - public SymTabELFContainer(int symTabSectionIndex) { - this.symTabSectionIndex = symTabSectionIndex; - } - - @Override - public String getContainerName() { - return ".symtab"; - } - - @Override - public int getSectionId() { - return symTabSectionIndex; } } }