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 align,
  57                       int sectIndex) {
  58 
  59         section = ElfByteBuffer.allocate(Elf64_Shdr.totalsize);
  60 
  61         // Return all 0's for NULL section
  62         if (sectIndex == 0) {
  63             sectNameTab.append('\0');
  64             shStrTabNrOfBytes += 1;
  65             data = null;
  66             hasrelocations = false;
  67             sectionIndex = 0;
  68             return;
  69         }
  70 
  71         section.putInt(Elf64_Shdr.sh_name.off, shStrTabNrOfBytes);
  72         sectNameTab.append(sectName).append('\0');
  73         shStrTabNrOfBytes += (sectName.getBytes().length + 1);
  74         name = sectName;
  75 
  76         section.putInt(Elf64_Shdr.sh_type.off, sectType);
  77         section.putLong(Elf64_Shdr.sh_flags.off, sectFlags);
  78         section.putLong(Elf64_Shdr.sh_addr.off, 0);
  79         section.putLong(Elf64_Shdr.sh_offset.off, 0);
  80 
  81         if (sectName.equals(".shstrtab")) {
  82             section.putLong(Elf64_Shdr.sh_size.off, shStrTabNrOfBytes);
  83             data = sectNameTab.toString().getBytes();
  84         }
  85         else {
  86             data = sectData;
  87             section.putLong(Elf64_Shdr.sh_size.off, sectData.length);
  88         }
  89 
  90         section.putLong(Elf64_Shdr.sh_entsize.off, 0);
  91 
  92         // Determine the entrysize
  93         // based on type of section
  94         switch (sectType) {
  95             case Elf64_Shdr.SHT_SYMTAB:
  96                 section.putLong(Elf64_Shdr.sh_entsize.off, Elf64_Sym.totalsize);
  97                 break;
  98             case Elf64_Shdr.SHT_RELA:
  99                 section.putLong(Elf64_Shdr.sh_entsize.off, Elf64_Rela.totalsize);
 100                 break;
 101             case Elf64_Shdr.SHT_REL:
 102                 section.putLong(Elf64_Shdr.sh_entsize.off, Elf64_Rel.totalsize);
 103                 break;
 104             default:
 105                 break;
 106         }
 107         section.putLong(Elf64_Shdr.sh_addralign.off, align);
 108 
 109         hasrelocations = hasRelocations;
 110         sectionIndex = sectIndex;
 111     }
 112 
 113     public String getName() {
 114         return name;
 115     }
 116 
 117     public long getSize() {
 118         return section.getLong(Elf64_Shdr.sh_size.off);
 119     }
 120 
 121     public int getDataAlign() {
 122         return ((int)section.getLong(Elf64_Shdr.sh_addralign.off));
 123     }
 124 
 125     // Alignment requirements for the Elf64_Shdr structures
 126     public static int getShdrAlign() {
 127         return (4);
 128     }
 129 
 130     public byte[] getArray() {
 131         return section.array();
 132     }
 133 
 134     public byte[] getDataArray() {
 135         return data;
 136     }
 137 
 138     public void setOffset(long offset) {
 139         section.putLong(Elf64_Shdr.sh_offset.off, offset);
 140     }
 141 
 142     public void setLink(int link) {
 143         section.putInt(Elf64_Shdr.sh_link.off, link);
 144     }
 145 
 146     public void setInfo(int info) {
 147         section.putInt(Elf64_Shdr.sh_info.off, info);
 148     }
 149 
 150     public long getOffset() {
 151         return (section.getLong(Elf64_Shdr.sh_offset.off));
 152     }
 153 
 154     public boolean hasRelocations() {
 155         return hasrelocations;
 156     }
 157 
 158     public int getSectionId() {
 159         return sectionIndex;
 160     }
 161 
 162 }
 163 
 164