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 28 import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SECTION_HEADER; 29 import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer; 30 31 final class PECoffSection { 32 private final ByteBuffer section; 33 private final byte[] data; 34 private final boolean hasrelocations; 35 private final int sectionIndex; 36 private final int align; 37 38 PECoffSection(String sectName, byte[] sectData0, int sectFlags0, int sectAlign, boolean hasRelocations, int sectIndex) { 39 40 section = PECoffByteBuffer.allocate(IMAGE_SECTION_HEADER.totalsize); 41 42 // If .oop.got section is empty, VM exits since .oop.got 43 // symbol ends up as external forwarded reference. 44 byte[] sectData = sectData0; 45 if (sectData0.length == 0) { 46 sectData = new byte[8]; 47 } 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 ? Name.length : IMAGE_SECTION_HEADER.Name.sz; 52 53 assert (sectAlign < 1 || sectAlign > 1024 || (sectAlign & (sectAlign - 1)) != 0) : "section alignment is not valid: " + sectAlign; 54 align = sectAlign; 55 56 // Using 32 because IMAGE_SCN_ALIGN_*BYTES is value + 1 57 int sectAlignBits = (32 - Integer.numberOfLeadingZeros(align)) << IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_SHIFT; 58 // Clear and set alignment bits 59 int sectFlags = (sectFlags0 & ~IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK) | (sectAlignBits & IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK); 60 61 section.put(Name, IMAGE_SECTION_HEADER.Name.off, max); 62 63 section.putInt(IMAGE_SECTION_HEADER.VirtualSize.off, 0); 64 section.putInt(IMAGE_SECTION_HEADER.VirtualAddress.off, 0); 65 section.putInt(IMAGE_SECTION_HEADER.SizeOfRawData.off, sectData.length); 66 section.putInt(IMAGE_SECTION_HEADER.PointerToLinenumbers.off, 0); 67 section.putChar(IMAGE_SECTION_HEADER.NumberOfLinenumbers.off, (char) 0); 68 69 section.putInt(IMAGE_SECTION_HEADER.Characteristics.off, sectFlags); 70 71 data = sectData; 72 hasrelocations = hasRelocations; 73 sectionIndex = sectIndex; 74 } 75 76 long getSize() { 77 return section.getInt(IMAGE_SECTION_HEADER.SizeOfRawData.off); 78 } 79 80 int getDataAlign() { 81 return (align); 82 } 83 84 // Alignment requirements for the IMAGE_SECTION_HEADER structures 85 static int getShdrAlign() { 86 return (4); 87 } 88 89 byte[] getArray() { 90 return section.array(); 91 } 92 93 byte[] getDataArray() { 94 return data; 95 } 96 97 void setOffset(long offset) { 98 section.putInt(IMAGE_SECTION_HEADER.PointerToRawData.off, (int) offset); 99 } 100 101 long getOffset() { 102 return (section.getInt(IMAGE_SECTION_HEADER.PointerToRawData.off)); 103 } 104 105 void setReloff(int offset) { 106 section.putInt(IMAGE_SECTION_HEADER.PointerToRelocations.off, offset); 107 } 108 109 void setRelcount(int count) { 110 // If the number of relocs is larger than 65K, then set 111 // the overflow bit. The real count will be written to 112 // the first reloc entry for this section. 113 if (count > 0xFFFF) { 114 int flags; 115 section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char) 0xFFFF); 116 flags = section.getInt(IMAGE_SECTION_HEADER.Characteristics.off); 117 flags |= IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_NRELOC_OVFL; 118 section.putInt(IMAGE_SECTION_HEADER.Characteristics.off, flags); 119 } else { 120 section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char) count); 121 } 122 } 123 124 boolean hasRelocations() { 125 return hasrelocations; 126 } 127 128 int getSectionId() { 129 return sectionIndex; 130 } 131 132 }