source: trunk/emx/src/emxomf/stripomf.c@ 3669

Last change on this file since 3669 was 828, checked in by bird, 22 years ago

Fixed warnings.

  • Property cvs2svn:cvs-rev set to 1.4
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1/* $Id: stripomf.c 828 2003-10-10 23:38:11Z bird $
2 *
3 * OMF Debug Info stripper.
4 *
5 * Copyright (c) 2003 InnoTek Systemberatung GmbH
6 * Author: knut st. osmundsen <bird@anduin.net>
7 *
8 *
9 * This file is part of GCC.
10 *
11 * GCC is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * GCC is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with GCC; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#ifdef __EMX__
34#include <io.h>
35#endif
36#include <sys/omflib.h>
37#include "defs.h"
38
39/*******************************************************************************
40* Defined Constants And Macros *
41*******************************************************************************/
42#ifndef min
43#define min(a,b) ((a) <= (b) ? (a) : (b))
44#endif
45
46
47/*******************************************************************************
48* Global Variables *
49*******************************************************************************/
50const char *pszPgm;
51
52
53
54/**
55 * Finds the base name in the filename.
56 * @returns Pointer within pszFile.
57 * @param pszFile Filename.
58 */
59static const char * mybasename(const char *pszFile)
60{
61 const char *psz;
62
63 psz = strrchr(pszFile, '\\');
64 if (!psz || strchr(psz, '/'))
65 psz = strrchr(pszFile, '/');
66 if (!psz || strchr(psz, ':'))
67 psz = strrchr(pszFile, ':');
68 if (psz)
69 psz++;
70 else
71 psz = pszFile;
72 return psz;
73}
74
75
76/**
77 * Main function.
78 * @returns 0 on success.
79 * @returns 8 on error.
80 * @param pszFile Name of file to strip.
81 */
82static int stripomf(const char *pszFile)
83{
84 FILE * pIn;
85 FILE * pTmp;
86 unsigned cb;
87 int rc = 8;
88
89 /*
90 * Open input file and output file.
91 */
92 pIn = fopen(pszFile, "rb+");
93 if (!pIn)
94 {
95 fprintf(stderr, "%s: failed to open file '%s'\n", pszPgm, pszFile);
96 return 8;
97 }
98
99 if ( fseek(pIn, 0, SEEK_END)
100 || (cb = ftell(pIn)) < 0
101 || fseek(pIn, 0, SEEK_SET)
102 )
103 {
104 fclose(pIn);
105 fprintf(stderr, "%s: failed to determin size of file '%s'\n", pszPgm, pszFile);
106 return 8;
107 }
108
109
110 pTmp = tmpfile();
111 if (pTmp)
112 {
113 int off = 0;
114 int iSegDef = 0;
115 int iName = 0;
116 int fPassThruPrev = 1;
117 int iNameTypes = -1;
118 int iNameSymbols = -1;
119 int iSegTypes = -1;
120 int iSegSymbols = -1;
121
122 while (off < cb)
123 {
124 #pragma pack(1)
125 static struct
126 {
127 struct omf_rec hdr;
128 char ach[2048];
129 } Rec;
130 #pragma pack()
131 int fPassThru = 1;
132
133 /* read header */
134 if (fread(&Rec.hdr, sizeof(Rec.hdr), 1, pIn) != 1)
135 {
136 fprintf(stderr, "%s: Failed reading from file '%s'\n", pszPgm, pszFile);
137 break;
138 }
139
140 if (Rec.hdr.rec_len > sizeof(Rec.ach))
141 {
142 fprintf(stderr, "%s: Record at offset %d in '%s' is too long\n", pszPgm, off, pszFile);
143 break;
144 }
145 if (Rec.hdr.rec_type == LIBHDR)
146 {
147 fprintf(stderr, "%s: OMF libraries are not yet supported ('%s').\n", pszPgm, pszFile);
148 break;
149 }
150
151 /* read the rest of the record. */
152 if (fread(Rec.ach, Rec.hdr.rec_len, 1, pIn) != 1)
153 {
154 fprintf(stderr, "%s: Failed reading from file '%s'\n", pszPgm, pszFile);
155 break;
156 }
157
158 fPassThru = 1;
159 switch (Rec.hdr.rec_type)
160 {
161 /*
162 * Need to clear the state.
163 */
164 case THEADR:
165 iNameTypes = iNameSymbols = iSegTypes = iSegSymbols = -1;
166 iName = iSegDef = 0;
167 break;
168
169 /*
170 * Need to find the name table indexs of $$SYMBOLS and $$TYPES.
171 */
172 case LNAMES:
173 {
174 int offRec = 0;
175 while (offRec < Rec.hdr.rec_len - 1)
176 {
177 int cchStr = Rec.ach[offRec++];
178 iName++;
179 if (cchStr == 9 && !strncmp(&Rec.ach[offRec], "$$SYMBOLS", 9))
180 iNameSymbols = iName;
181 else if (cchStr == 7 && !strncmp(&Rec.ach[offRec], "$$TYPES", 7))
182 iNameTypes = iName;
183 offRec += cchStr;
184 }
185 break;
186 }
187
188 /*
189 * Need to find the name table indexs of $$SYMBOLS and $$TYPES.
190 */
191 case SEGDEF:
192 case SEGDEF|REC32:
193 {
194 int iName;
195 int offRec = (Rec.ach[0] >> 5) ? 1 : 4;
196 offRec += (Rec.hdr.rec_type & REC32) ? 4 : 2;
197 /** @todo support name indexes higher than 127 */
198 iName = Rec.ach[offRec];
199 iSegDef++;
200 if (iName == iNameSymbols)
201 {
202 iSegSymbols = iSegDef;
203 }
204 else if (iName == iNameTypes)
205 {
206 iSegTypes = iSegDef;
207 }
208 break;
209 }
210
211 /*
212 * Linenumbers - no question.
213 */
214 case LINNUM:
215 case LINNUM|REC32:
216 fPassThru = 0;
217 break;
218
219 /*
220 * LEDATA if it's $$SYMBOLS or $$TYPES.
221 */
222 case LEDATA:
223 case LEDATA|REC32:
224 { /* @todo indexes higher than 127. */
225 int iSeg = Rec.ach[0];
226 if (iSeg == iSegTypes || iSeg == iSegSymbols)
227 fPassThru = 0;
228 break;
229 }
230
231 /*
232 * If previous record was debug info this one is fixups to it
233 * and must be removed.
234 */
235 case FIXUPP:
236 case FIXUPP|REC32:
237 fPassThru = fPassThruPrev;
238 break;
239 }
240
241 if ( fPassThru
242 && fwrite(&Rec, Rec.hdr.rec_len + sizeof(Rec.hdr), 1, pTmp) != 1)
243 {
244 fprintf(stderr, "%s: Failed to write to tempfile.\n", pszPgm);
245 break;
246 }
247
248 off += Rec.hdr.rec_len + sizeof(Rec.hdr);
249 fPassThruPrev = fPassThru;
250 } /* read loop */
251
252
253 /*
254 * Did we succeed reading?
255 */
256 if (off >= cb)
257 {
258 /*
259 * Now we must copy the result from the temp file to pszFile.
260 */
261 int cbToCopy;
262 if ( (cbToCopy = ftell(pTmp)) >= 0
263 && !fseek(pIn, 0, SEEK_SET)
264 && !fseek(pTmp, 0, SEEK_SET))
265 {
266 int cbNewSize = cbToCopy;
267 while (cbToCopy > 0)
268 {
269 static char achBuffer[0x10000];
270 int cbRead = min(sizeof(achBuffer), cbToCopy);
271 cbRead = fread(achBuffer, 1, cbRead, pTmp);
272 if (cbRead <= 0)
273 {
274 fprintf(stderr, "%s: Failed reading from tempfile\n", pszPgm);
275 break;
276 }
277
278 if (fwrite(achBuffer, cbRead, 1, pIn) != 1)
279 {
280 fprintf(stderr, "%s: Failed to write to '%s'\n", pszPgm, pszFile);
281 break;
282 }
283
284 cbToCopy -= cbRead;
285 } /* tmp -> file loop */
286
287 /* success? */
288 if (cbToCopy == 0)
289 {
290 fflush(pIn);
291 _chsize(fileno(pIn), cbNewSize);
292 rc = 0;
293 }
294 }
295 else
296 fprintf(stderr, "%s: Failed to seek to start.\n", pszPgm);
297 }
298
299 fclose(pTmp);
300 }
301 else
302 fprintf(stderr, "%s: failed to open temporary file\n", pszPgm);
303
304 fclose(pIn);
305 return rc;
306}
307
308
309/**
310 * Show program usage.
311 * @returns 8 (prefered program exist code).
312 */
313static int usage(void)
314{
315 fputs("stripomf " VERSION INNOTEK_VERSION " -- "
316 "Copyright (c) 2003 by InnoTek Systemberatung GmbH\n\n"
317 "Usage: stripomf <input_file>\n\n",
318 stderr);
319 return 8;
320}
321
322
323int main(int argc, char **argv)
324{
325 int argi;
326
327 pszPgm = mybasename(argv[0]);
328 _response (&argc, &argv);
329 _wildcard (&argc, &argv);
330
331#ifdef __EMX__
332 if (_isterm (1))
333 setvbuf (stdout, NULL, _IOLBF, BUFSIZ);
334 else
335 setvbuf (stdout, NULL, _IOFBF, BUFSIZ);
336#endif /* __EMX__ */
337
338
339 /*
340 * Arguments
341 */
342 for (argi = 1; argi < argc; argi++)
343 {
344 if (argv[argi][0] == '-')
345 {
346 /* option!*/
347 return usage();
348 }
349 else
350 {
351 int rc = stripomf(argv[argi]);
352 if (rc != 0)
353 return rc;
354 }
355 }
356
357 return 0;
358}
Note: See TracBrowser for help on using the repository browser.