00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "elfstruc.h"
00022 #include "htatom.h"
00023 #include "htelf.h"
00024 #include "htelfsym.h"
00025 #include "httag.h"
00026 #include "formats.h"
00027 #include "snprintf.h"
00028
00029 #include <stdlib.h>
00030
00031 static int_hash elf_st_bind[] =
00032 {
00033 {ELF_STB_LOCAL, "local"},
00034 {ELF_STB_GLOBAL, "global"},
00035 {ELF_STB_WEAK, "weak"},
00036 {0, 0}
00037 };
00038
00039 static int_hash elf_st_type[] =
00040 {
00041 {ELF_STT_NOTYPE, "no type"},
00042 {ELF_STT_OBJECT, "object"},
00043 {ELF_STT_FUNC, "func"},
00044 {ELF_STT_SECTION, "section"},
00045 {ELF_STT_FILE, "file"},
00046 {ELF_STT_COMMON, "common"},
00047 {0, 0}
00048 };
00049
00050 static ht_view *htelfsymboltable_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00051 {
00052 ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)group->get_shared_data();
00053
00054 if (elf_shared->ident.e_ident[ELF_EI_CLASS]!=ELFCLASS32) return 0;
00055
00056 UINT skip = elf_shared->symtables;
00057 UINT symtab_shidx = ELF_SHN_UNDEF;
00058 for (UINT i=1; i<elf_shared->sheaders.count; i++) {
00059 if ((elf_shared->sheaders.sheaders32[i].sh_type == ELF_SHT_SYMTAB) || (elf_shared->sheaders.sheaders32[i].sh_type==ELF_SHT_DYNSYM)) {
00060 if (!skip--) {
00061 symtab_shidx = i;
00062 break;
00063 }
00064 }
00065 }
00066 if (!isValidELFSectionIdx(elf_shared, symtab_shidx)) return NULL;
00067
00068 FILEOFS h = elf_shared->sheaders.sheaders32[symtab_shidx].sh_offset;
00069
00070
00071 FILEOFS sto = elf_shared->sheaders.sheaders32[elf_shared->sheaders.sheaders32[symtab_shidx].sh_link].sh_offset;
00072
00073 char *symtab_name;
00074 if (!isValidELFSectionIdx(elf_shared, elf_shared->header32.e_shstrndx) ||
00075 file->seek(elf_shared->sheaders.sheaders32[elf_shared->header32.e_shstrndx].sh_offset+elf_shared->sheaders.sheaders32[symtab_shidx].sh_name)
00076 || !((symtab_name=fgetstrz(file))))
00077 symtab_name = "?";
00078
00079 char desc[128];
00080 ht_snprintf(desc, sizeof desc, DESC_ELF_SYMTAB, symtab_name, symtab_shidx);
00081 free(symtab_name);
00082
00083 ht_uformat_viewer *v=new ht_uformat_viewer();
00084 v->init(b, desc, VC_EDIT | VC_SEARCH, file, group);
00085
00086 ht_mask_sub *m = new ht_mask_sub();
00087 m->init(file, 0);
00088
00089 register_atom(ATOM_ELF_ST_BIND, elf_st_bind);
00090
00091 char t[256];
00092 ht_snprintf(t, sizeof t, "* ELF symtab at offset %08x", h);
00093
00094 m->add_mask(t);
00095
00096 m->add_mask("idx binding type value size section name");
00097
00098 bool elf_bigendian = (elf_shared->ident.e_ident[ELF_EI_DATA] == ELFDATA2MSB);
00099 UINT symnum = elf_shared->sheaders.sheaders32[symtab_shidx].sh_size / sizeof (ELF_SYMBOL32);
00100 for (UINT i=0; i<symnum; i++) {
00101 ELF_SYMBOL32 sym;
00102 file->seek(h+i*sizeof (ELF_SYMBOL32));
00103 file->read(&sym, sizeof sym);
00104 create_host_struct(&sym, ELF_SYMBOL32_struct, elf_shared->byte_order);
00105 file->seek(sto+sym.st_name);
00106 char *name = fgetstrz(file);
00107
00108 if (!name) continue;
00109
00110 char *tt = t;
00111
00112 tt += ht_snprintf(tt, sizeof t - (tt-t), "%04x ", i);
00113
00114 char *bind = matchhash(ELF32_ST_BIND(sym.st_info), elf_st_bind);
00115 if (bind) {
00116 tt += ht_snprintf(tt, sizeof t - (tt-t), "%-8s ", bind);
00117 } else {
00118 tt += ht_snprintf(tt, sizeof t - (tt-t), "? (%d) ", ELF32_ST_BIND(sym.st_info));
00119 }
00120
00121 char *type = matchhash(ELF32_ST_TYPE(sym.st_info), elf_st_type);
00122 if (type) {
00123 tt += ht_snprintf(tt, sizeof t - (tt-t), "%-8s ", type);
00124 } else {
00125 tt += ht_snprintf(tt, sizeof t - (tt-t), "? (%d) ", ELF32_ST_TYPE(sym.st_info));
00126 }
00127
00128 FILEOFS so = elf_shared->sheaders.sheaders32[elf_shared->header32.e_shstrndx].sh_offset;
00129 tt = tag_make_edit_dword(tt, h+i*sizeof (ELF_SYMBOL32)+4, elf_bigendian ? tag_endian_big : tag_endian_little);
00130 *tt++ = ' ';
00131 tt = tag_make_edit_dword(tt, h+i*sizeof (ELF_SYMBOL32)+8, elf_bigendian ? tag_endian_big : tag_endian_little);
00132 *tt++ = ' ';
00133 *tt = 0;
00134 switch (sym.st_shndx) {
00135 case ELF_SHN_UNDEF:
00136 tt += ht_snprintf(tt, sizeof t - (tt-t), "*undefined ");
00137 break;
00138 case ELF_SHN_ABS:
00139 tt += ht_snprintf(tt, sizeof t - (tt-t), "*absolute ");
00140 break;
00141 case ELF_SHN_COMMON:
00142 tt += ht_snprintf(tt, sizeof t - (tt-t), "*common ");
00143 break;
00144 default: {
00145 char *s;
00146 if (!isValidELFSectionIdx(elf_shared, sym.st_shndx)
00147 || file->seek(so+elf_shared->sheaders.sheaders32[sym.st_shndx].sh_name)
00148 || !((s = fgetstrz(file)))) s = "?";
00149 tt += ht_snprintf(tt, sizeof t - (tt-t), "%-11s ", s);
00150 free(s);
00151 break;
00152 }
00153 }
00154 tt += ht_snprintf(tt, sizeof t - (tt-t), "%s", name);
00155 free(name);
00156 m->add_mask(t);
00157 }
00158
00159 v->insertsub(m);
00160 return v;
00161 }
00162
00163 format_viewer_if htelfsymboltable_if = {
00164 htelfsymboltable_init,
00165 0
00166 };