1 /* 2 * Copyright (c) 2016, 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.elf; 25 26 import java.nio.ByteBuffer; 27 import java.nio.ByteOrder; 28 29 import jdk.tools.jaotc.binformat.elf.Elf; 30 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr; 31 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr; 32 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rel; 33 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela; 34 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym; 35 import jdk.tools.jaotc.binformat.elf.ElfByteBuffer; 36 37 public class ElfSection { 38 String name; 39 ByteBuffer section; 40 byte [] data; 41 boolean hasrelocations; 42 int sectionIndex; 43 44 /** 45 * String holding section name strings 46 */ 47 private static StringBuilder sectNameTab = new StringBuilder(); 48 49 /** 50 * Keeps track of bytes in section string table since strTabContent.length() 51 * is number of chars, not bytes. 52 */ 53 private static int shStrTabNrOfBytes = 0; 54 55 public ElfSection(String sectName, byte [] sectData, int sectFlags, 56 int sectType, boolean hasRelocations, int sectIndex) { 57 58 long align; 59 60 section = ElfByteBuffer.allocate(Elf64_Shdr.totalsize); 61 62 // Return all 0's for NULL section 63 if (sectIndex == 0) { 64 sectNameTab.append('\0'); 65 shStrTabNrOfBytes += 1; 66 data = null; 67 hasrelocations = false; 68 sectionIndex = 0; 69 return; 70 } 71 72 section.putInt(Elf64_Shdr.sh_name.off, shStrTabNrOfBytes); 73 sectNameTab.append(sectName).append('\0'); 74 shStrTabNrOfBytes += (sectName.getBytes().length + 1); 75 name = sectName; 76 77 section.putInt(Elf64_Shdr.sh_type.off, sectType); 78 section.putLong(Elf64_Shdr.sh_flags.off, sectFlags); 79 section.putLong(Elf64_Shdr.sh_addr.off, 0); 80 section.putLong(Elf64_Shdr.sh_offset.off, 0); 81 82 if (sectName.equals(".shstrtab")) { 83 section.putLong(Elf64_Shdr.sh_size.off, shStrTabNrOfBytes); 84 data = sectNameTab.toString().getBytes(); 85 } 86 else { 87 data = sectData; 88 section.putLong(Elf64_Shdr.sh_size.off, sectData.length); 89 } 90 91 section.putLong(Elf64_Shdr.sh_entsize.off, 0); 92 93 // Determine the alignment and entrysize 94 // based on type of section 95 switch (sectType) { 96 case Elf64_Shdr.SHT_PROGBITS: 97 if ((sectFlags & Elf64_Shdr.SHF_EXECINSTR) != 0) 98 align = 16; 99 else 100 align = 4; 101 break; 102 case Elf64_Shdr.SHT_SYMTAB: 103 align = 8; 104 section.putLong(Elf64_Shdr.sh_entsize.off, Elf64_Sym.totalsize); 105 break; 106 case Elf64_Shdr.SHT_STRTAB: 107 align = 1; 108 break; 109 case Elf64_Shdr.SHT_RELA: 110 align = 8; 111 section.putLong(Elf64_Shdr.sh_entsize.off, Elf64_Rela.totalsize); 112 break; 113 case Elf64_Shdr.SHT_REL: 114 align = 8; 115 section.putLong(Elf64_Shdr.sh_entsize.off, Elf64_Rel.totalsize); 116 break; 117 case Elf64_Shdr.SHT_NOBITS: 118 align = 4; 119 break; 120 default: 121 align = 8; 122 break; 123 } 124 section.putLong(Elf64_Shdr.sh_addralign.off, align); 125 126 hasrelocations = hasRelocations; 127 sectionIndex = sectIndex; 128 } 129 130 public String getName() { 131 return name; 132 } 133 134 public long getSize() { 135 return section.getLong(Elf64_Shdr.sh_size.off); 136 } 137 138 public int getDataAlign() { 139 return ((int)section.getLong(Elf64_Shdr.sh_addralign.off)); 140 } 141 142 // Alignment requirements for the Elf64_Shdr structures 143 public static int getShdrAlign() { 144 return (4); 145 } 146 147 public byte[] getArray() { 148 return section.array(); 149 } 150 151 public byte[] getDataArray() { 152 return data; 153 } 154 155 public void setOffset(long offset) { 156 section.putLong(Elf64_Shdr.sh_offset.off, offset); 157 } 158 159 public void setLink(int link) { 160 section.putInt(Elf64_Shdr.sh_link.off, link); 161 } 162 163 public void setInfo(int info) { 164 section.putInt(Elf64_Shdr.sh_info.off, info); 165 } 166 167 public long getOffset() { 168 return (section.getLong(Elf64_Shdr.sh_offset.off)); 169 } 170 171 public boolean hasRelocations() { 172 return hasrelocations; 173 } 174 175 public int getSectionId() { 176 return sectionIndex; 177 } 178 179 } 180 181