1
/* ``The contents of this file are subject to the Erlang Public License,
2
* Version 1.1, (the "License"); you may not use this file except in
3
* compliance with the License. You should have received a copy of the
4
* Erlang Public License along with this software. If not, it can be
5
* retrieved via the world wide web at http://www.erlang.org/.
7
* Software distributed under the License is distributed on an "AS IS"
8
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
* the License for the specific language governing rights and limitations
12
* The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
* Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
* AB. All Rights Reserved.''
19
** This mini tool fixes an incompatibility between
20
** Microsoft's tools, who dont like the virtual size being put in
21
** the physical address field, but rely on the raw size field for
22
** sizing the ".bss" section.
23
** This fixes some of the problems with linking gcc compiled objects
24
** together with MSVC dito.
26
** Courtesy DJ Delorie for describing the COFF file format on
27
** http://www.delorie.com/djgpp/doc/coff/
28
** The coff structures are fetched from Microsofts headers though.
37
#include <winnt.h> /* Structure definitions for PE (COFF) */
39
static int dump_edit(char *filename, int edit);
40
static int v_printf(char *format, ...);
46
int main(int argc, char **argv)
54
fprintf(stderr,"Format : %s [-e] [-v] <filename>\n", progname);
58
findex < argc && (*argv[findex] == '-' || *argv[findex] == '/');
60
switch (argv[findex][1]) {
69
fprintf(stderr, "%s: unknown option %s\n", progname, argv[findex]);
73
fprintf(stderr,"%s: No filenames given.\n", progname);
76
for(; findex < argc; ++findex)
77
if ((ret = dump_edit(argv[findex],edit)) != 0)
82
int dump_edit(char *filename, int edit)
84
FILE *f = fopen(filename, (edit) ? "r+b" : "rb");
85
IMAGE_FILE_HEADER filhdr;
86
IMAGE_SECTION_HEADER scnhdr;
90
fprintf(stderr, "%s: cannot open %s.\n", progname, filename);
94
if (fread(&filhdr, sizeof(filhdr), 1, f) == 0) {
95
fprintf(stderr,"%s: Could not read COFF header from %s,"
96
" is this a PE (COFF) file?\n", progname, filename);
100
v_printf("File: %s\n", filename);
101
v_printf("Magic number: 0x%08x\n", filhdr.Machine);
102
v_printf("Number of sections: %d\n",filhdr.NumberOfSections);
104
if (fseek(f, (long) filhdr.SizeOfOptionalHeader, SEEK_CUR) != 0) {
105
fprintf(stderr,"%s: Could not read COFF optional header from %s,"
106
" is this a PE (COFF) file?\n", progname, filename);
111
for (i = 0; i < filhdr.NumberOfSections; ++i) {
112
if (fread(&scnhdr, sizeof(scnhdr), 1, f) == 0) {
113
fprintf(stderr,"%s: Could not read section header from %s,"
114
" is this a PE (COFF) file?\n", progname, filename);
118
v_printf("Section %s:\n", scnhdr.Name);
119
v_printf("Physical address: 0x%08x\n", scnhdr.Misc.PhysicalAddress);
120
v_printf("Size: 0x%08x\n", scnhdr.SizeOfRawData);
121
if (scnhdr.Misc.PhysicalAddress != 0 &&
122
scnhdr.SizeOfRawData == 0) {
123
printf("Section header %s in file %s will confuse MSC linker, "
124
"virtual size is 0x%08x and raw size is 0\n",
125
scnhdr.Name, filename, scnhdr.Misc.PhysicalAddress,
126
scnhdr.SizeOfRawData);
128
scnhdr.SizeOfRawData = scnhdr.Misc.PhysicalAddress;
129
scnhdr.Misc.PhysicalAddress = 0;
130
if (fseek(f, (long) -((long)sizeof(scnhdr)), SEEK_CUR) != 0 ||
131
fwrite(&scnhdr, sizeof(scnhdr), 1, f) == 0) {
132
fprintf(stderr,"%s: could not edit file %s.\n",
137
printf("Edited object, virtual size is now 0, and "
138
"raw size is 0x%08x.\n", scnhdr.SizeOfRawData);
140
printf("Specify option '-e' to correct the problem.\n");
149
static int v_printf(char *format, ...)
154
va_start(ap, format);
155
ret = vfprintf(stdout, format, ap);