/* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * Copyright (c) 2005, Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the University of California, Los Angeles nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Created Sep 5, 2005 */ package com.oracle.max.elf; import java.io.*; import java.util.*; /** * The <code>ELFStringTable</code> class represents a string table that is * present in the ELF file. A string table section contains a sequence of * null-terminated strings and can be indexed by integers to obtain the * string corresponding to the sequence of characters starting at the * specified index up to (and not including) the next null character. */ public class ELFStringTable { protected final Map<Integer, String> stringMap; protected byte[] data; protected char [] stringTable; protected int position; protected ELFSectionHeaderTable.Entry sectionEntry; /** * The constructor for the <code>ELFStringTable</code> class creates a new * string table with the specified number of bytes reserved for its internal * string storage. * @param header the ELF header of the file * @param sectionEntry the section header table entry corresponding to this string * table */ public ELFStringTable(ELFHeader header, ELFSectionHeaderTable.Entry sectionEntry) { data = new byte[(int) sectionEntry.getSize()]; stringMap = new HashMap<Integer, String>(); this.sectionEntry = sectionEntry; stringTable = new char[50]; stringTable[0] = '\0'; position = 1; } public ELFStringTable(ELFHeader header) { stringMap = new HashMap<Integer, String>(); stringTable = new char[50]; stringTable[0] = '\0'; position = 1; } public void setSection(ELFSectionHeaderTable.Entry sectionEntry) { data = new byte[(int) sectionEntry.getSize()]; this.sectionEntry = sectionEntry; } /** * The <code>read()</code> method reads this string table from the specified * file, beginning at the specified offset and continuing for the length * of the section. * @param f the random access file to read the data from * @throws IOException if there is a problem reading the file */ public void read(RandomAccessFile f) throws IOException { if (data.length == 0) { return; } f.seek(sectionEntry.getOffset()); int read = 0; while (read < data.length) { read += f.read(data, read, data.length - read); } } /** * The <code>getString()</code> method gets a string in this section corresponding * to the specified index. Since Java strings are not null-terminated as the * ones in this section are, this method employs a hash table to remember frequently * accessed strings. * @param ind the index into the section for which to retrieve the string * @return a string corresponding to reading bytes at the specified index up to * and not including the next null character */ public String getString(int ind) { if (ind >= data.length) { return ""; } String str = stringMap.get(ind); if (str == null) { final StringBuffer buf = new StringBuffer(); for (int pos = ind; pos < data.length; pos++) { final byte b = data[pos]; if (b == 0) { break; } buf.append((char) b); } str = buf.toString(); stringMap.put(ind, str); } return str; } public void addStringInTable(String str) { int addSize = str.length(); int index = 0; char [] addString = str.toCharArray(); while (index < addSize) { stringTable[position++] = addString[index++]; } stringTable[position++] = '\0'; } public int getIndex(String str) { int index = -1; int strSize = str.length(); int strCount = 0; int count = 0; if (str.equalsIgnoreCase("\0")) { return 0; } while (count < position && index == -1) { if (str.charAt(strCount) == stringTable[count]) { while (count <= position && strCount < strSize && str.charAt(strCount) == stringTable[count]) { if (index == -1) { if (stringTable[count - 1] != '\0') { count++; break; } else { index = count; } } count++; strCount++; } if (strCount < strSize - 1 || stringTable[count] != '\0') { index = -1; strCount = 0; } } else { count++; } } return index; } public int getStringLength() { return position; } public void write64ToFile(ELFDataOutputStream os, RandomAccessFile fis) throws IOException { for (int count = 0; count < position; count++) { fis.write(stringTable[count]); } } }