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

htpef.cc

Go to the documentation of this file.
00001 /* 
00002  *      HT Editor
00003  *      htpef.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 "pefstruc.h"
00022 #include "log.h"
00023 #include "htpef.h"
00024 #include "htpefhd.h"
00025 #include "htpefimp.h"
00026 #include "htpefimg.h"
00027 #include "htendian.h"
00028 #include "stream.h"
00029 #include "tools.h"
00030 
00031 #include <stdlib.h>
00032 
00033 format_viewer_if *htpef_ifs[] = {
00034         &htpefheader_if,
00035         &htpefimports_if,
00036         &htpefimage_if,
00037         0
00038 };
00039 
00040 static ht_view *htpef_init(bounds *b, ht_streamfile *file, ht_format_group *format_group)
00041 {
00042         byte id[12];
00043         file->seek(0);
00044         file->read(&id, sizeof id);
00045         if (memcmp(id, "Joy!peff", 8)) return NULL;
00046         PEF_ARCH arch;
00047         if (memcmp(id+8, "pwpc", 4) == 0) {
00048                 arch = PEFARCH_PowerPC;
00049         } else if (memcmp(id+8, "m68k", 4) == 0) {
00050                 arch = PEFARCH_M68K;
00051         } else return NULL;
00052 
00053         ht_pef *g = new ht_pef();
00054         g->init(b, file, htpef_ifs, format_group, 0);
00055         return g;
00056 }
00057 
00058 format_viewer_if htpef_if = {
00059         htpef_init,
00060         0
00061 };
00062 
00063 /*
00064  *      CLASS ht_pef
00065  */
00066 void ht_pef::init(bounds *b, ht_streamfile *f, format_viewer_if **ifs, ht_format_group *format_group, FILEOFS header_ofs)
00067 {
00068         ht_format_group::init(b, VO_SELECTABLE | VO_BROWSABLE | VO_RESIZE, DESC_PEF, f, false, true, 0, format_group);
00069         VIEW_DEBUG_NAME("ht_pef");
00070 
00071         LOG("%s: PEF: found header at %08x", file->get_filename(), header_ofs);
00072 
00073         ht_pef_shared_data *pef_shared=(ht_pef_shared_data *)malloc(sizeof(ht_pef_shared_data));
00074         memset(pef_shared, 0, sizeof *pef_shared);
00075         
00076         shared_data = pef_shared;
00077         /* always big-endian */
00078         pef_shared->byte_order = big_endian;
00079         pef_shared->header_ofs = 0;
00080 
00081         pef_shared->imports.funcs = new ht_clist();
00082         pef_shared->imports.funcs->init();
00083 
00084         pef_shared->imports.libs = new ht_clist();
00085         pef_shared->imports.libs->init();
00086 
00087         pef_shared->v_imports = NULL;
00088         
00089         /* read (container) header */
00090         file->seek(header_ofs);
00091         file->read(&pef_shared->contHeader, sizeof pef_shared->contHeader);
00092         create_host_struct(&pef_shared->contHeader, PEF_CONTAINER_HEADER_struct, pef_shared->byte_order);
00093 
00094         if (memcmp(pef_shared->contHeader.architecture, "pwpc", 4) == 0) {
00095                 pef_shared->arch = PEFARCH_PowerPC;
00096         } else if (memcmp(pef_shared->contHeader.architecture, "m68k", 4) == 0) {
00097                 pef_shared->arch = PEFARCH_M68K;
00098         } else return;
00099 
00100         /* read section headers */
00101         pef_shared->sheaders.count = pef_shared->contHeader.sectionCount;
00102         pef_shared->sheaders.sheaders = (PEF_SECTION_HEADER*)
00103                 malloc(pef_shared->sheaders.count*sizeof (PEF_SECTION_HEADER));
00104         for (uint i=0; i<pef_shared->sheaders.count; i++) {
00105                 file->read(&pef_shared->sheaders.sheaders[i], sizeof pef_shared->sheaders.sheaders[i]);
00106                 create_host_struct(&pef_shared->sheaders.sheaders[i], PEF_SECTION_HEADER_struct, pef_shared->byte_order);
00107                 // FIXME: hack
00108                 pef_shared->sheaders.sheaders[i].defaultAddress = i*0x100000;
00109                 if (!pef_shared->loader_info_header_ofs
00110                 && pef_shared->sheaders.sheaders[i].sectionKind == PEF_SK_Loader) {
00111                         pef_shared->loader_info_header_ofs = pef_shared->sheaders.sheaders[i].containerOffset;
00112                 }
00113         }
00114 
00115         if (pef_shared->loader_info_header_ofs) {
00116                 file->seek(pef_shared->loader_info_header_ofs);
00117                 file->read(&pef_shared->loader_info_header, sizeof pef_shared->loader_info_header);
00118                 create_host_struct(&pef_shared->loader_info_header, PEF_LOADER_INFO_HEADER_struct, pef_shared->byte_order);
00119         }
00120 
00121         /* init ifs */
00122         ht_format_group::init_ifs(ifs);
00123 }
00124 
00125 void ht_pef::done()
00126 {
00127         ht_format_group::done();
00128         
00129         ht_pef_shared_data *pef_shared = (ht_pef_shared_data*)shared_data;
00130         if (pef_shared->imports.funcs) {
00131                 pef_shared->imports.funcs->destroy();
00132                 delete pef_shared->imports.funcs;
00133         }
00134         if (pef_shared->imports.libs) {
00135                 pef_shared->imports.libs->destroy();
00136                 delete pef_shared->imports.libs;
00137         }
00138         free(shared_data);
00139 }
00140 
00141 #define RELOC_BASE              0x10000000
00142 #define RELOC_STEPPING  0x100000
00143 #define RELOC_LIMIT             0xffffffff
00144                         
00145 /*static uint32 pef_invent_reloc_address(uint si, PEF_SECTION_HEADER *s, uint scount)
00146 {
00147         elf32_addr a=RELOC_BASE;
00148         while (a<RELOC_LIMIT-s[si].sh_size) {
00149                 bool ok=true;
00150                 for (UINT i=0; i<scount; i++) {
00151                         if ((s[i].sh_type==ELF_SHT_PROGBITS) && (s[i].sh_addr) &&
00152                         ((a>=s[i].sh_addr) && (a<s[i].sh_addr+s[i].sh_size))) {
00153                                 ok=false;
00154                                 break;
00155                         }
00156                 }
00157                 if (ok) return a;
00158                 a+=RELOC_STEPPING;
00159         }
00160         return 0;
00161 }*/
00162 
00163 /*
00164  *      address conversion routines
00165  */
00166 
00167 bool pef_phys_and_mem_section(PEF_SECTION_HEADER *s)
00168 {
00169         return (s->sectionKind <= 1) || (s->sectionKind == 3) || (s->sectionKind == 6);
00170 }
00171 
00172 bool pef_valid_section(PEF_SECTION_HEADER *s)
00173 {
00174         return (s->sectionKind <= 3) || (s->sectionKind == 6);
00175 }
00176 
00177 bool pef_addr_to_ofs(pef_section_headers *section_headers, PEFAddress addr, dword *ofs)
00178 {
00179         PEF_SECTION_HEADER *s = section_headers->sheaders;
00180         for (UINT i=0; i < section_headers->count; i++) {
00181                 if ((pef_phys_and_mem_section(s)) &&
00182                 (addr.a32 >= s->defaultAddress) && (addr.a32 < s->defaultAddress+s->packedSize)) {
00183                         *ofs = addr.a32 - s->defaultAddress + s->containerOffset;
00184                         return true;
00185                 }
00186                 s++;
00187         }
00188         return false;
00189 }
00190 
00191 bool pef_addr_to_section(pef_section_headers *section_headers, PEFAddress addr, int *section)
00192 {
00193         PEF_SECTION_HEADER *s = section_headers->sheaders;
00194         for (UINT i = 0; i < section_headers->count; i++) {
00195                 if ((pef_valid_section(s)) &&
00196                 (addr.a32 >= s->defaultAddress) && (addr.a32 < s->defaultAddress + s->totalSize)) {
00197                         *section = i;
00198                         return true;
00199                 }
00200                 s++;
00201         }
00202         return false;
00203 }
00204 
00205 bool pef_addr_is_valid(pef_section_headers *section_headers, PEFAddress addr)
00206 {
00207         PEF_SECTION_HEADER *s = section_headers->sheaders;
00208         for (UINT i=0; i<section_headers->count; i++) {
00209                 if ((pef_valid_section(s)) &&
00210                 (addr.a32 >= s->defaultAddress) && (addr.a32 < s->defaultAddress + s->totalSize)) {
00211                         return true;
00212                 }
00213                 s++;
00214         }
00215         return false;
00216 }
00217 
00218 /*
00219  *      offset conversion routines
00220  */
00221 
00222 bool pef_ofs_to_addr(pef_section_headers *section_headers, dword ofs, PEFAddress *addr)
00223 {
00224         PEF_SECTION_HEADER *s = section_headers->sheaders;
00225         for (UINT i = 0; i < section_headers->count; i++) {
00226                 if ((pef_phys_and_mem_section(s)) &&
00227                 (ofs>=s->containerOffset) && (ofs<s->containerOffset+s->packedSize)) {
00228                         addr->a32 = ofs - s->containerOffset + s->defaultAddress;
00229                         return true;
00230                 }
00231                 s++;
00232         }
00233         return false;
00234 }
00235 
00236 bool pef_ofs_to_section(pef_section_headers *section_headers, dword ofs, int *section)
00237 {
00238         PEF_SECTION_HEADER *s=section_headers->sheaders;
00239         for (UINT i=0; i<section_headers->count; i++) {
00240                 if ((pef_valid_section(s)) &&
00241                 (ofs >= s->containerOffset) && (ofs<s->containerOffset+s->packedSize)) {
00242                         *section = i;
00243                         return true;
00244                 }
00245                 s++;
00246         }
00247         return false;
00248 }
00249 
00250 /*
00251  *      ht_pef_reloc_entry
00252  */
00253 #include "relfile.h"
00254 class ht_pef_reloc_entry: public Object {
00255 public:
00256         
00257 //      ht_elf32_reloc_entry(UINT symtabidx, elf32_addr offset, UINT type, UINT symbolidx, elf32_addr addend, ht_elf_shared_data *data, ht_streamfile *file);
00258 };
00259 
00260 /*
00261  *      ht_pef_reloc_file
00262  */
00263 
00264 class ht_pef_reloc_file: public ht_reloc_file {
00265 protected:
00266         ht_pef_shared_data *data;
00267 /* overwritten */
00268         virtual void    reloc_apply(Object *reloc, byte *data);
00269         virtual bool    reloc_unapply(Object *reloc, byte *data);
00270 public:
00271 
00272 void init(ht_streamfile *s, bool own_s, ht_pef_shared_data *d)
00273 {
00274         ht_reloc_file::init(s, own_s);
00275         data = d;
00276 }
00277 
00278 };

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