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

out_sym.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      out_sym.cc
00004  *
00005  *      Copyright (C) 1999-2002 Sebastian Biallas (sb@web-productions.de)
00006  *      Copyright (C) 2002 Stefan Weyergraf (stefan@weyergraf.de)
00007  *
00008  *      This program is free software; you can redistribute it and/or modify
00009  *      it under the terms of the GNU General Public License version 2 as
00010  *      published by the Free Software Foundation.
00011  *
00012  *      This program is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU General Public License
00018  *      along with this program; if not, write to the Free Software
00019  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020  */
00021 
00022 #include "analy_names.h"
00023 #include "htdebug.h"
00024 #include "htinfo.h"
00025 #include "out_html.h"
00026 #include "tools.h"
00027 #include "x86dis.h"
00028 #include "string.h"
00029 
00030 /*
00031  *
00032  *      Format of .SYM files:
00033  * ==========================================================================
00034  *      1. Header, see (1)
00035  *      2. "seg_count" "Segment tables", see (2)
00036  *      3. Terminator ???, see (A)
00037  *
00038  *   (1) Header
00039  * ==========================================================================
00040  *      The header holds the number of symbols+something ('q_count'),
00041  *      the number of segments ('seg_count') and the module_name.
00042  *      I dont know what the other fields stand for...
00043  *      The header always has 32 bytes.
00044  *
00045  *      (2) Segment table (starts 16-byte aligned)
00046  * ==========================================================================
00047  *      (2.1) Segment Header
00048  *      - number of symbols "n"
00049  *      - pointer to "Symbol pointer table" see (2.3), relative to start of
00050  *        this header
00051  *
00052  *      (2.2) Symbol table
00053  *      - usually has "n+1" entries of "Symbol table entry", see (3)
00054  *      - first entry usually is segment descriptor (informative)
00055  *
00056  *      (2.3) Symbol pointer table
00057  *      - consists of "n" entries of 16-bit pointers to a "Symbol table entry"
00058  *        (pointers are relative to "Segment Header")
00059  *
00060  *   (3) Symbol table entry
00061  * ==========================================================================
00062  *      contains 32-bit integer ("the address"), followed by a counted
00063  *      (Pascal-style) string ("the name").
00064  *
00065  *   (A) Appendix A - Unsure
00066  * ==========================================================================
00067  *      observed files always had an additional 4 bytes appended.
00068  *      bytes are either 00,00,00,04 or 00,00,00,06
00069  */
00070 
00071 struct ImageSymHeader {
00072         dword file_size HTPACKED;               // in 16-byte blocks
00073         word entry_seg HTPACKED;
00074         word u0 HTPACKED;                               // 0000
00075         word u1 HTPACKED;                               // 0015 (some flags ?, 0014 for 16-bit .SYM ?)
00076         word seg_count HTPACKED;
00077         dword u2 HTPACKED;                              // 04020002 (some flags ?)
00078         byte    module_name[16] HTPACKED;
00079 };
00080 
00081 struct ImageSymSegHeader {
00082         word next_rec_ofs HTPACKED;             // in 16-byte blocks (ring list, last points to first)
00083         word sym_count HTPACKED;
00084         word sym_ptr_table_ptr HTPACKED;
00085         word seg_idx HTPACKED;
00086         dword seg_start HTPACKED;
00087         dword seg_size HTPACKED;
00088 };
00089 
00090 struct ImageSymDescriptor {
00091         dword address HTPACKED;
00092 //      byte  name_len HTPACKED;
00093 //   name;
00094 //   ^^^^ pascal string
00095 };
00096 
00097 /*
00098  *
00099  */
00100 
00101 #define MAX_BYTES_PER_SEGMENT           0xff00
00102 #define MAX_SYMBOLS_PER_SEGMENT 0x4000
00103 
00104 static void write_sym(ht_stream *stream, dword addr, char *name, UINT *bytes_written)
00105 {
00106         ImageSymDescriptor desc;
00107         desc.address = addr;
00108         stream->write(&desc, sizeof desc); // FIXME: endianess !
00109         putstrp(stream, name);
00110         *bytes_written += sizeof desc + 1 + strlen(name);
00111 }
00112 
00113 static void g(ht_stream *stream, Symbol *s, UINT *bytes_written, UINT *symbols_written, word *ptr_table)
00114 {
00115         if (*bytes_written >= MAX_BYTES_PER_SEGMENT) return;
00116         if (*symbols_written >= MAX_SYMBOLS_PER_SEGMENT) return;
00117 
00118         dword addr;
00119         if (s->location->addr->byteSize() == sizeof addr) {
00120                 s->location->addr->putIntoArray((byte*)&addr);
00121 //          addr -= 0xbff70000; /* FIXME: hack for kernel32.dll */
00122         } else {
00123                 addr = 0;
00124         }
00125         
00126         ptr_table[*symbols_written] = *bytes_written;
00127         write_sym(stream, addr, s->name, bytes_written);
00128         
00129         (*symbols_written) ++;
00130 }
00131 
00132 static void align16(ht_streamfile *file, UINT *bytes_written)
00133 {
00134         byte c = 0;
00135         while (*bytes_written % 16) {
00136                 file->write(&c, 1);
00137                 (*bytes_written) ++;
00138         }
00139 }
00140  
00141 int export_to_sym(Analyser *analy, ht_streamfile *file)
00142 {
00143         if ((!analy) || (!file)) return /*HTML_OUTPUT_ERR_GENERIC*/1;
00144         if (analy->active) return /*HTML_OUTPUT_ERR_ANALY_NOT_FINISHED*/1;
00145 
00146         char *module_name = "TEST";
00147         ImageSymHeader head;
00148         ImageSymSegHeader seg_head;
00149 
00150 // write dummy header
00151         memset(&head, 0, sizeof head);
00152         file->write(&head, sizeof head);
00153 
00154 
00155 /* foreach ($seg) { */
00156 
00157 // write dummy seg header
00158         memset(&seg_head, 0, sizeof seg_head);
00159         file->write(&seg_head, sizeof seg_head);
00160 
00161         UINT bytes_written = sizeof seg_head, symbols_written = 0;
00162 
00163         write_sym(file, 0xff000000, "_TEXT", &bytes_written);
00164 
00165         word *ptr_table = (word*)malloc(MAX_SYMBOLS_PER_SEGMENT * sizeof *ptr_table);
00166 
00167         Symbol *sym = NULL;
00168         while ((sym = analy->enumSymbols(sym))) {
00169                 g(file, sym, &bytes_written, &symbols_written, ptr_table);
00170         }
00171         
00172         UINT sym_ptr_table_ptr = bytes_written;
00173 
00174         // FIXME: endianess !
00175         file->write(ptr_table, sizeof *ptr_table * symbols_written);
00176         bytes_written += sizeof *ptr_table * symbols_written;
00177         free(ptr_table);
00178 
00179         align16(file, &bytes_written);
00180 
00181         // FIXME: wrong code order, endianess !
00182         dword terminator = 0x04000000;
00183         file->write(&terminator, sizeof terminator);
00184         bytes_written += 4;
00185 
00186         file->seek(0x0020);
00187 // write segment header
00188         seg_head.next_rec_ofs = 0x0002;
00189         seg_head.sym_count = symbols_written;
00190         seg_head.sym_ptr_table_ptr = sym_ptr_table_ptr;
00191         seg_head.seg_idx = 1;
00192         seg_head.seg_start = 0;
00193         seg_head.seg_size = 0x0000ffff;
00194         // FIXME: endianess !
00195         file->write(&seg_head, sizeof seg_head);
00196         
00197 /* } */
00198 
00199 
00200         bytes_written += sizeof head;
00201         file->seek(0);
00202 // write header
00203         head.file_size = (bytes_written-1) / 16;
00204         head.entry_seg = 0;
00205         head.u0 = 0;
00206         head.u1 = 0x0015;
00207         head.seg_count = 1;
00208         head.u2 = 0x04020002;
00209         memcpy(head.module_name, module_name, MIN(strlen(module_name), sizeof head.module_name));
00210         // FIXME: endianess !
00211         file->write(&head, sizeof head);
00212 
00213         return 0;
00214 }
00215 

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