< prev index next >

src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java

Print this page




  29 import java.util.List;
  30 import java.util.Map;
  31 
  32 import jdk.tools.jaotc.binformat.BinaryContainer;
  33 import jdk.tools.jaotc.binformat.ByteContainer;
  34 import jdk.tools.jaotc.binformat.CodeContainer;
  35 import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
  36 import jdk.tools.jaotc.binformat.Relocation;
  37 import jdk.tools.jaotc.binformat.Relocation.RelocType;
  38 import jdk.tools.jaotc.binformat.Symbol;
  39 import jdk.tools.jaotc.binformat.Symbol.Binding;
  40 import jdk.tools.jaotc.binformat.Symbol.Kind;
  41 
  42 import jdk.tools.jaotc.binformat.elf.ElfSymbol;
  43 import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
  44 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
  45 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr;
  46 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
  47 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
  48 
  49 public class JELFRelocObject {
  50 
  51     private final BinaryContainer binContainer;
  52 
  53     private final ElfContainer elfContainer;
  54 
  55     private final int segmentSize;
  56 
  57     public JELFRelocObject(BinaryContainer binContainer, String outputFileName) {
  58         this.binContainer = binContainer;
  59         this.elfContainer = new ElfContainer(outputFileName);
  60         this.segmentSize = binContainer.getCodeSegmentSize();
  61     }
  62 










  63     private static ElfSection createByteSection(ArrayList<ElfSection> sections,
  64                                                 String sectName,
  65                                                 byte[] scnData,
  66                                                 boolean hasRelocs,
  67                                                 int align,
  68                                                 int scnFlags,
  69                                                 int scnType) {
  70 
  71         ElfSection sect = new ElfSection(sectName, scnData, scnFlags, scnType,
  72                                          hasRelocs, align, sections.size());
  73         // Add this section to our list
  74         sections.add(sect);
  75 
  76         return (sect);
  77     }
  78 
  79     private void createByteSection(ArrayList<ElfSection> sections,
  80                                    ByteContainer c, int scnFlags) {
  81         ElfSection sect;
  82         boolean hasRelocs = c.hasRelocations();


 278         ElfRelocTable elfRelocTable = new ElfRelocTable(sections.size());
 279         /*
 280          * For each of the symbols with associated relocation records, create a Elf relocation entry.
 281          */
 282         for (Map.Entry<Symbol, List<Relocation>> entry : relocationTable.entrySet()) {
 283             List<Relocation> relocs = entry.getValue();
 284             Symbol symbol = entry.getKey();
 285 
 286             for (Relocation reloc : relocs) {
 287                 createRelocation(symbol, reloc, elfRelocTable);
 288             }
 289         }
 290 
 291         for (Map.Entry<Symbol, Relocation> entry : binContainer.getUniqueRelocationTable().entrySet()) {
 292             createRelocation(entry.getKey(), entry.getValue(), elfRelocTable);
 293         }
 294 
 295         return (elfRelocTable);
 296     }
 297 
 298     private static void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) {
 299         RelocType relocType = reloc.getType();
 300 
 301         int elfRelocType = getELFRelocationType(relocType);
 302         ElfSymbol sym = (ElfSymbol) symbol.getNativeSymbol();
 303         int symno = sym.getIndex();
 304         int sectindex = reloc.getSection().getSectionId();
 305         int offset = reloc.getOffset();
 306         int addend = 0;
 307 
 308         switch (relocType) {
 309             case JAVA_CALL_DIRECT:
 310             case STUB_CALL_DIRECT:
 311             case FOREIGN_CALL_INDIRECT_GOT: {
 312                 // Create relocation entry
 313                 addend = -4; // Size in bytes of the patch location
 314                 // Relocation should be applied at the location after call operand
 315                 offset = offset + reloc.getSize() + addend;
 316                 break;
 317             }
 318             case JAVA_CALL_INDIRECT:
 319             case METASPACE_GOT_REFERENCE:
 320             case EXTERNAL_PLT_TO_GOT: {
 321                 addend = -4; // Size of 32-bit address of the GOT
 322                 /*
 323                  * Relocation should be applied before the test instruction to the move instruction.
 324                  * reloc.getOffset() points to the test instruction after the instruction that loads the address of
 325                  * polling page. So set the offset appropriately.
 326                  */
 327                 offset = offset + addend;
 328                 break;
 329             }
 330             case EXTERNAL_GOT_TO_PLT: {
 331                 // this is load time relocations
 332                 break;
 333             }
 334             default:
 335                 throw new InternalError("Unhandled relocation type: " + relocType);
 336         }
 337         elfRelocTable.createRelocationEntry(sectindex, offset, symno, elfRelocType, addend);
 338     }
 339 
 340     private static int getELFRelocationType(RelocType relocType) {
 341         int elfRelocType = 0; // R_<ARCH>_NONE if #define'd to 0 for all values of ARCH
 342         switch (ElfTargetInfo.getElfArch()) {
 343             case Elf64_Ehdr.EM_X86_64:
 344                 // Return R_X86_64_* entries based on relocType
 345                 if (relocType == RelocType.JAVA_CALL_DIRECT ||
 346                     relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
 347                     elfRelocType = Elf64_Rela.R_X86_64_PLT32;
 348                 } else if (relocType == RelocType.STUB_CALL_DIRECT) {
 349                     elfRelocType = Elf64_Rela.R_X86_64_PC32;
 350                 } else if (relocType == RelocType.JAVA_CALL_INDIRECT) {
 351                     elfRelocType = Elf64_Rela.R_X86_64_NONE;
 352                 } else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
 353                            relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
 354                     elfRelocType = Elf64_Rela.R_X86_64_PC32;
 355                 } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
 356                     elfRelocType = Elf64_Rela.R_X86_64_64;
 357                 } else {
 358                     assert false : "Unhandled relocation type: " + relocType;
 359                 }
 360                 break;
 361             default:
 362                 System.out.println("Relocation Type mapping: Unhandled architecture");
 363         }
 364         return elfRelocType;
 365     }
 366 
 367     private static void createElfRelocSections(ArrayList<ElfSection> sections,
 368                                                ElfRelocTable elfRelocTable,
 369                                                int symtabsectidx) {
 370 
 371         // Grab count before we create new sections
 372         int count = sections.size();
 373 
 374         for (int i = 0; i < count; i++) {
 375             if (elfRelocTable.getNumRelocs(i) > 0) {
 376                 ElfSection sect = sections.get(i);
 377                 String relname = ".rela" + sect.getName();
 378                 ElfSection relocSection = createByteSection(sections, relname,
 379                                                             elfRelocTable.getRelocData(i),
 380                                                             false, 8, 0, Elf64_Shdr.SHT_RELA);
 381                 relocSection.setLink(symtabsectidx);
 382                 relocSection.setInfo(sect.getSectionId());
 383             }
 384         }
 385     }



 386 }


  29 import java.util.List;
  30 import java.util.Map;
  31 
  32 import jdk.tools.jaotc.binformat.BinaryContainer;
  33 import jdk.tools.jaotc.binformat.ByteContainer;
  34 import jdk.tools.jaotc.binformat.CodeContainer;
  35 import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
  36 import jdk.tools.jaotc.binformat.Relocation;
  37 import jdk.tools.jaotc.binformat.Relocation.RelocType;
  38 import jdk.tools.jaotc.binformat.Symbol;
  39 import jdk.tools.jaotc.binformat.Symbol.Binding;
  40 import jdk.tools.jaotc.binformat.Symbol.Kind;
  41 
  42 import jdk.tools.jaotc.binformat.elf.ElfSymbol;
  43 import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
  44 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
  45 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr;
  46 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
  47 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
  48 
  49 public abstract class JELFRelocObject {
  50 
  51     private final BinaryContainer binContainer;
  52 
  53     private final ElfContainer elfContainer;
  54 
  55     private final int segmentSize;
  56 
  57     protected JELFRelocObject(BinaryContainer binContainer, String outputFileName) {
  58         this.binContainer = binContainer;
  59         this.elfContainer = new ElfContainer(outputFileName);
  60         this.segmentSize = binContainer.getCodeSegmentSize();
  61     }
  62 
  63     public static JELFRelocObject newInstance(BinaryContainer binContainer, String outputFileName) {
  64         String archStr = System.getProperty("os.arch").toLowerCase();
  65         if (archStr.equals("amd64") || archStr.equals("x86_64")) {
  66             return new AMD64JELFRelocObject(binContainer, outputFileName);
  67         } else  if (archStr.equals("aarch64")) {
  68             return new AArch64JELFRelocObject(binContainer, outputFileName);
  69         }
  70         throw new InternalError("Unsupported platform: " + archStr);
  71     }
  72 
  73     private static ElfSection createByteSection(ArrayList<ElfSection> sections,
  74                                                 String sectName,
  75                                                 byte[] scnData,
  76                                                 boolean hasRelocs,
  77                                                 int align,
  78                                                 int scnFlags,
  79                                                 int scnType) {
  80 
  81         ElfSection sect = new ElfSection(sectName, scnData, scnFlags, scnType,
  82                                          hasRelocs, align, sections.size());
  83         // Add this section to our list
  84         sections.add(sect);
  85 
  86         return (sect);
  87     }
  88 
  89     private void createByteSection(ArrayList<ElfSection> sections,
  90                                    ByteContainer c, int scnFlags) {
  91         ElfSection sect;
  92         boolean hasRelocs = c.hasRelocations();


 288         ElfRelocTable elfRelocTable = new ElfRelocTable(sections.size());
 289         /*
 290          * For each of the symbols with associated relocation records, create a Elf relocation entry.
 291          */
 292         for (Map.Entry<Symbol, List<Relocation>> entry : relocationTable.entrySet()) {
 293             List<Relocation> relocs = entry.getValue();
 294             Symbol symbol = entry.getKey();
 295 
 296             for (Relocation reloc : relocs) {
 297                 createRelocation(symbol, reloc, elfRelocTable);
 298             }
 299         }
 300 
 301         for (Map.Entry<Symbol, Relocation> entry : binContainer.getUniqueRelocationTable().entrySet()) {
 302             createRelocation(entry.getKey(), entry.getValue(), elfRelocTable);
 303         }
 304 
 305         return (elfRelocTable);
 306     }
 307 





































































 308     private static void createElfRelocSections(ArrayList<ElfSection> sections,
 309                                                ElfRelocTable elfRelocTable,
 310                                                int symtabsectidx) {
 311 
 312         // Grab count before we create new sections
 313         int count = sections.size();
 314 
 315         for (int i = 0; i < count; i++) {
 316             if (elfRelocTable.getNumRelocs(i) > 0) {
 317                 ElfSection sect = sections.get(i);
 318                 String relname = ".rela" + sect.getName();
 319                 ElfSection relocSection = createByteSection(sections, relname,
 320                                                             elfRelocTable.getRelocData(i),
 321                                                             false, 8, 0, Elf64_Shdr.SHT_RELA);
 322                 relocSection.setLink(symtabsectidx);
 323                 relocSection.setInfo(sect.getSectionId());
 324             }
 325         }
 326     }
 327 
 328     abstract void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable);
 329 
 330 }
< prev index next >