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