1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jdk.tools.jaotc.binformat.pecoff; 25 26 import java.nio.ByteBuffer; 27 import java.nio.ByteOrder; 28 29 import jdk.tools.jaotc.binformat.pecoff.PECoff; 30 import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SECTION_HEADER; 31 import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer; 32 33 public class PECoffSection { 34 ByteBuffer section; 35 byte [] data; 36 boolean hasrelocations; 37 int sectionIndex; 38 int align; 39 40 public PECoffSection(String sectName, byte [] sectData, int sectFlags, 41 boolean hasRelocations, int sectIndex) { 42 43 section = PECoffByteBuffer.allocate(IMAGE_SECTION_HEADER.totalsize); 44 45 // bug: If JVM.oop.got section is empty, VM exits since JVM.oop.got 46 // symbol ends up as external forwarded reference. 47 if (sectData.length == 0) sectData = new byte[8]; 48 49 // Copy only Max allowed bytes to Section Entry 50 byte [] Name = sectName.getBytes(); 51 int max = Name.length <= IMAGE_SECTION_HEADER.Name.sz ? 52 Name.length : IMAGE_SECTION_HEADER.Name.sz; 53 54 section.put(Name, IMAGE_SECTION_HEADER.Name.off, max); 55 56 section.putInt(IMAGE_SECTION_HEADER.VirtualSize.off, 0); 57 section.putInt(IMAGE_SECTION_HEADER.VirtualAddress.off, 0); 58 section.putInt(IMAGE_SECTION_HEADER.SizeOfRawData.off, sectData.length); 59 section.putInt(IMAGE_SECTION_HEADER.PointerToLinenumbers.off, 0); 60 section.putChar(IMAGE_SECTION_HEADER.NumberOfLinenumbers.off, (char)0); 61 62 section.putInt(IMAGE_SECTION_HEADER.Characteristics.off, sectFlags); 63 64 // Extract alignment from Characteristics field 65 int alignshift = (sectFlags & IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK) >> 66 IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_SHIFT; 67 68 // Use 8 byte alignment if not specified 69 if (alignshift == 0) 70 alignshift = 3; 71 else 72 --alignshift; 73 74 align = 1 << alignshift; 75 76 data = sectData; 77 hasrelocations = hasRelocations; 78 sectionIndex = sectIndex; 79 } 80 81 public long getSize() { 82 return section.getInt(IMAGE_SECTION_HEADER.SizeOfRawData.off); 83 } 84 85 public int getDataAlign() { 86 return (align); 87 } 88 89 // Alignment requirements for the IMAGE_SECTION_HEADER structures 90 public static int getShdrAlign() { 91 return (4); 92 } 93 94 public byte[] getArray() { 95 return section.array(); 96 } 97 98 public byte[] getDataArray() { 99 return data; 100 } 101 102 public void setOffset(long offset) { 103 section.putInt(IMAGE_SECTION_HEADER.PointerToRawData.off, (int)offset); 104 } 105 106 public long getOffset() { 107 return (section.getInt(IMAGE_SECTION_HEADER.PointerToRawData.off)); 108 } 109 110 public void setReloff(int offset) { 111 section.putInt(IMAGE_SECTION_HEADER.PointerToRelocations.off, offset); 112 } 113 114 public void setRelcount(int count) { 115 // If the number of relocs is larger than 65K, then set 116 // the overflow bit. The real count will be written to 117 // the first reloc entry for this section. 118 if (count > 0xFFFF) { 119 int flags; 120 section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char)0xFFFF); 121 flags = section.getInt(IMAGE_SECTION_HEADER.Characteristics.off); 122 flags |= IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_NRELOC_OVFL; 123 section.putInt(IMAGE_SECTION_HEADER.Characteristics.off, flags); 124 } 125 else { 126 section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char)count); 127 } 128 } 129 130 public boolean hasRelocations() { 131 return hasrelocations; 132 } 133 134 public int getSectionId() { 135 return sectionIndex; 136 } 137 138 } 139 140