Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

htelfrel.cc

Go to the documentation of this file.
00001 /* 
00002  *      HT Editor
00003  *      htelfrel.cc
00004  *
00005  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "elfstruc.h"
00022 #include "htatom.h"
00023 #include "htelf.h"
00024 #include "htelfrel.h"
00025 #include "httag.h"
00026 #include "formats.h"
00027 #include "snprintf.h"
00028 
00029 #include <stdlib.h>
00030 
00031 static int_hash elf_r_386_type[] =
00032 {
00033         {ELF_R_386_NONE,                "ELF_R_386_NONE"},
00034         {ELF_R_386_32,                  "ELF_R_386_32"},
00035         {ELF_R_386_PC32,                "ELF_R_386_PC32"},
00036         {ELF_R_386_GOT32,               "ELF_R_386_GOT32"},
00037         {ELF_R_386_PLT32,               "ELF_R_386_PLT32"},
00038         {ELF_R_386_COPY,                "ELF_R_386_COPY"},
00039         {ELF_R_386_GLOB_DAT,    "ELF_R_386_GLOB_DAT"},
00040         {ELF_R_386_JMP_SLOT,    "ELF_R_386_JMP_SLOT"},
00041         {ELF_R_386_RELATIVE,    "ELF_R_386_RELATIVE"},
00042         {ELF_R_386_GOTOFF,              "ELF_R_386_GOTOFF"},
00043         {ELF_R_386_GOTPC,               "ELF_R_386_GOTPC"},
00044         {0, 0}
00045 };
00046 
00047 static ht_view *htelfreloctable_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00048 {
00049         ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)group->get_shared_data();
00050 
00051         if ((elf_shared->ident.e_ident[ELF_EI_CLASS]!=ELFCLASS32) ||
00052         (elf_shared->ident.e_ident[ELF_EI_DATA]!=ELFDATA2LSB) ||
00053         (elf_shared->header32.e_machine!=ELF_EM_386)) return NULL;
00054         
00055         UINT skip = elf_shared->reloctables;
00056         UINT reloctab_shidx = ELF_SHN_UNDEF;
00057         UINT reloctab_sh_type = ELF_SHT_NULL;
00058         for (UINT i=1; i<elf_shared->sheaders.count; i++) {
00059                 if ((elf_shared->sheaders.sheaders32[i].sh_type==ELF_SHT_REL) || (elf_shared->sheaders.sheaders32[i].sh_type==ELF_SHT_RELA)) {
00060                         if (!skip--) {
00061                                 reloctab_sh_type=elf_shared->sheaders.sheaders32[i].sh_type;
00062                                 reloctab_shidx=i;
00063                                 break;
00064                         }
00065                 }
00066         }
00067         if (!isValidELFSectionIdx(elf_shared, reloctab_shidx)) return NULL;
00068 
00069         FILEOFS h=elf_shared->sheaders.sheaders32[reloctab_shidx].sh_offset;
00070         
00071         /* section index of associated symbol table */
00072         int si_symbol=elf_shared->sheaders.sheaders32[reloctab_shidx].sh_link;
00073         
00074         /* section index of section to be relocated */
00075         int si_dest=elf_shared->sheaders.sheaders32[reloctab_shidx].sh_info;
00076 
00077         char *reloctab_name;
00078         if (!isValidELFSectionIdx(elf_shared, elf_shared->header32.e_shstrndx)
00079         || file->seek(elf_shared->sheaders.sheaders32[elf_shared->header32.
00080         e_shstrndx].sh_offset+elf_shared->sheaders.sheaders32[reloctab_shidx].sh_name)
00081         || !((reloctab_name=fgetstrz(file))))
00082                 reloctab_name = "?";
00083         char desc[128];
00084         ht_snprintf(desc, sizeof desc, DESC_ELF_RELOCTAB, reloctab_name, reloctab_shidx);
00085         free(reloctab_name);
00086         
00087         ht_uformat_viewer *v=new ht_uformat_viewer();
00088         v->init(b, desc, VC_EDIT, file, group);
00089         
00090         ht_mask_sub *m=new ht_mask_sub();
00091         m->init(file, 0);
00092         
00093         register_atom(ATOM_ELF_R_386_TYPE, elf_r_386_type);
00094 
00095         char t[256];    /* FIXME: possible buffer overflow ! */
00096         ht_snprintf(t, sizeof t, "* ELF relocation table at offset %08x, relocates section %d, symtab %d", h, si_dest, si_symbol);
00097 
00098         m->add_mask(t);
00099 
00100         bool elf_bigendian = (elf_shared->ident.e_ident[ELF_EI_DATA] == ELFDATA2MSB);
00101 
00102         switch (reloctab_sh_type) {
00103                 case ELF_SHT_REL: {
00104                         m->add_mask("destofs  symidx type");
00105                         UINT relnum=elf_shared->sheaders.sheaders32[reloctab_shidx].sh_size / sizeof (ELF_REL32);
00106                         for (UINT i=0; i<relnum; i++) {
00107                                 char *tt=t;
00108                                 /* dest offset */
00109                                 tt=tag_make_edit_dword(tt, h+i*sizeof (ELF_REL32), elf_bigendian ? tag_endian_big : tag_endian_little);
00110                                 *tt++=' ';
00111                                 /* symbol (table idx) */
00112                                 tt=tag_make_edit_word(tt, h+i*sizeof (ELF_REL32)+4+1, elf_bigendian ? tag_endian_big : tag_endian_little);
00113                                 *tt++=' ';
00114                                 *tt++=' ';
00115                                 *tt++=' ';
00116                                 /* type */
00117                                 tt=tag_make_edit_byte(tt, h+i*sizeof (ELF_REL32)+4);
00118                                 *tt++='(';
00119                                 /* type */
00120                                 tt=tag_make_desc_byte(tt, h+i*sizeof (ELF_REL32)+4, ATOM_ELF_R_386_TYPE);
00121                                 *tt++=')';
00122                                 *tt=0;
00123                                 m->add_mask(t);
00124                         }
00125                         break;
00126                 }
00127                 case ELF_SHT_RELA: {
00128                         m->add_mask("destofs  symidx addend   type");
00129                         UINT relnum=elf_shared->sheaders.sheaders32[reloctab_shidx].sh_size / sizeof (ELF_RELA32);
00130                         for (UINT i=0; i<relnum; i++) {
00131                                 char *tt=t;
00132                                 /* dest offset */
00133                                 tt=tag_make_edit_dword(tt, h+i*sizeof (ELF_RELA32), elf_bigendian ? tag_endian_big : tag_endian_little);
00134                                 *tt++=' ';
00135                                 /* symbol (table idx) */
00136                                 tt=tag_make_edit_word(tt, h+i*sizeof (ELF_RELA32)+4+1, elf_bigendian ? tag_endian_big : tag_endian_little);
00137                                 *tt++=' ';
00138                                 *tt++=' ';
00139                                 *tt++=' ';
00140                                 /* addend */
00141                                 tt=tag_make_edit_dword(tt, h+i*sizeof (ELF_RELA32)+4+4, elf_bigendian ? tag_endian_big : tag_endian_little);
00142                                 *tt++=' ';
00143                                 /* type */
00144                                 tt=tag_make_edit_byte(tt, h+i*sizeof (ELF_RELA32)+4);
00145                                 *tt++='(';
00146                                 /* type */
00147                                 tt=tag_make_desc_byte(tt, h+i*sizeof (ELF_RELA32)+4, ATOM_ELF_R_386_TYPE);
00148                                 *tt++=')';
00149                                 *tt=0;
00150                                 m->add_mask(t);
00151                         }
00152                         break;
00153                 }
00154         }
00155         
00156         v->insertsub(m);
00157         return v;
00158 }
00159 
00160 format_viewer_if htelfreloctable_if = {
00161         htelfreloctable_init,
00162         0
00163 };

Generated on Fri May 7 21:15:33 2004 by doxygen 1.3.5