/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.linker;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Symbol {
/**
* symbol table - page 4-25, figure 4-15 <code>typedef struct { Elf32_Word
* st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info;
* unsigned char st_other; Elf32_Half st_shndx; } Elf32_Sym;</code>.
*/
public static final int SHN_ABS = 0xFFFFFFF1;
public static final int SHN_COMMON = 0xFFFFFFF2;
public static final int SHN_UNDEF = 0;
// Symbol binding
public static final int STB_LOCAL = 0;
public static final int STB_GLOBAL = 1;
public static final int STB_WEAK = 2;
public static final int STB_LOPROC = 13;
public static final int STB_HIPROC = 15;
// Symbol type
public static final int STT_NOTYPE = 0;
public static final int STT_OBJECT = 1;
public static final int STT_FUNC = 2;
public static final int STT_SECTION = 3;
public static final int STT_FILE = 4;
public static final int STT_LOPROC = 13;
public static final int STT_HIPROC = 15;
private int st_name;
private long st_value;
private long st_size;
private int st_info;
private int st_other;
private int st_shndx;
private Elf elf;
public Symbol(Elf elf, InputStream in) throws IOException {
this.elf = elf;
if (elf.isClass32()) {
st_name = LoadUtil.little32(in);
st_value = LoadUtil.loadAddr(in, elf.e_ident);
st_size = LoadUtil.loadXword(in, elf.e_ident);
st_info = LoadUtil.little8(in);
st_other = LoadUtil.little8(in);
st_shndx = LoadUtil.little16(in);
} else {
st_name = LoadUtil.little32(in);
st_info = LoadUtil.little8(in);
st_other = LoadUtil.little8(in);
st_shndx = LoadUtil.little16(in);
st_value = LoadUtil.loadAddr(in, elf.e_ident);
st_size = LoadUtil.loadXword(in, elf.e_ident);
}
}
public Symbol(Elf elf, String name, int value, Section section) {
this.elf = elf;
if (name != null) {
this.st_name = elf.addString(name);
} else {
this.st_name = 0;
}
this.st_value = value;
if (section != null) {
this.st_shndx = elf.getSectionIndex(section);
} else {
this.st_shndx = SHN_UNDEF;
}
this.st_info = (STB_GLOBAL << 4) | (STT_FUNC & 0xF);
}
public int store(OutputStream out) throws IOException {
int cnt = 0;
if (elf.isClass32()) {
cnt += StoreUtil.little32(out, st_name);
cnt += StoreUtil.storeAddr(out, elf.e_ident, st_value);
cnt += StoreUtil.storeXword(out, elf.e_ident, st_size);
cnt += StoreUtil.little8(out, st_info);
cnt += StoreUtil.little8(out, st_other);
cnt += StoreUtil.little16(out, st_shndx);
} else {
cnt += StoreUtil.little32(out, st_name);
cnt += StoreUtil.little8(out, st_info);
cnt += StoreUtil.little8(out, st_other);
cnt += StoreUtil.little16(out, st_shndx);
cnt += StoreUtil.storeAddr(out, elf.e_ident, st_value);
cnt += StoreUtil.storeXword(out, elf.e_ident, st_size);
}
return cnt;
}
public String toString() {
return getName() + ", " + getValue();
}
public String getName() {
return elf.getString(st_name);
}
public long getValue() {
return st_value;
}
public void setValue(long v) {
st_value = v;
}
public long getSize() {
return st_size;
}
public void setSize(long v) {
st_size = v;
}
public int getBind() {
return (st_info >> 4);
}
public void setBind(int v) {
setInfo(v, getType());
}
public int getType() {
return (st_info & 0xF);
}
public void setType(int v) {
setInfo(getBind(), v);
}
public void setInfo(int bind, int type) {
st_info = (bind << 4) | (type & 0xf);
}
public int getOther() {
return st_other;
}
public void setOther(int v) {
st_other = v;
}
public int getSectionIndex() {
return st_shndx;
}
public Section getSection() {
return elf.getSection(st_shndx);
}
public boolean isAbs() {
return (st_shndx == SHN_ABS);
}
public void setAbs() {
st_shndx = SHN_ABS;
}
public boolean isUndef() {
return (st_shndx == SHN_UNDEF);
}
public void setUndef() {
st_shndx = SHN_UNDEF;
}
public void print() {
System.out.println(" ----- Symbol -----");
System.out.println(" st_name : " + getName());
System.out.println(" st_value : " + Long.toString(st_value, 16));
System.out.println(" st_size : " + Long.toString(st_size, 16));
System.out.println(" st_info : " + Integer.toString(st_info, 16));
System.out.println(" st_other : " + Integer.toString(st_other, 16));
System.out.println(" st_section : " + st_shndx /* + getSection().getName() */);
}
}