1
/* Tool to make gzipped second stage binary
3
Copyright (C) 1996,1998 Jakub Jelinek
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26
unsigned char buffer[2048];
27
unsigned char buffer2[2048];
28
unsigned short diffs[4][2048];
30
unsigned int lastv[4];
35
#define MAX_CHANGE 65535
37
void save(FILE *out, int len, int type)
45
if (fread (buffer, 1, i, f) != i) {
46
fprintf(stderr, "read %d from arg3 type %d failed\n", i, type);
49
if (fread (buffer2, 1, i, e) != i) {
50
fprintf(stderr, "read %d from arg4 type %d failed\n", i, type);
53
for (j = 0; j < i; j++) {
54
if (buffer[j] != buffer2[j]) {
55
if (buffer2[j] == buffer[j] + 4) {
56
if (curoff + j > lastv[type] + MAX_CHANGE) {
57
if (type || !prevlen || curoff + j >= prevoff + MAX_CHANGE)
59
k = lastv[type] + MAX_CHANGE;
60
if (k < prevoff - prevlen)
64
diffs[type][ndiffs[type]] = k - lastv[type];
68
diffs[type][ndiffs[type]] = curoff + j - lastv[type];
69
lastv[type] = curoff + j;
71
} else if (buffer2[j] == buffer[j] + 16) {
72
if (curoff + j > lastv[type+1] + MAX_CHANGE) {
73
if (type || !prevlen || curoff + j >= prevoff + MAX_CHANGE)
75
k = lastv[type+1] + MAX_CHANGE;
76
if (k < prevoff - prevlen)
80
diffs[type+1][ndiffs[type+1]] = k - lastv[type+1];
84
diffs[type+1][ndiffs[type+1]] = curoff + j - lastv[type+1];
85
lastv[type+1] = curoff + j;
88
fprintf(stderr, "Strange, small and large images differ in something"
89
" different to R_SPARC_32 and R_SPARC_HI22\n");
94
if (fwrite (buffer, 1, i, out) != i) {
95
fprintf(stderr, "write %d failed\n", i);
107
fprintf(stderr, "Distance between two changes larger than %dK %d %d %d\n",
108
MAX_CHANGE / 1024, type, curoff + j, lastv[type]);
112
int main(int argc, char **argv)
115
int reloc = SMALL_RELOC;
116
int first_start, first_end, second_start, second_end;
117
int end, rodata_start, rodata_end;
123
if (!strcmp (argv[i], "-a")) {
128
f = fopen(argv[i++], "r");
129
while (fgets (buffer, 256, f)) {
133
if (sscanf(buffer, "%x %*c %s\n", &addr, sym) == 2) {
134
if (!strcmp (sym, "start"))
136
else if (!strcmp (sym, "main_text_start"))
137
first_start = addr - reloc;
138
else if (!strcmp (sym, "main_text_end"))
139
first_end = addr - reloc;
140
else if (!strcmp (sym, "main_data_start"))
141
second_start = addr - reloc;
142
else if (!strcmp (sym, "main_data_end"))
143
second_end = addr - reloc;
144
else if (!strcmp (sym, "main_rodata_start"))
145
rodata_start = addr - reloc;
146
else if (!strcmp (sym, "main_rodata_end"))
147
rodata_end = addr - reloc;
148
else if (!strcmp (sym, "__bss_start"))
153
f = fopen(argv[i++], "r");
154
e = fopen(argv[i++], "r");
155
g = fopen(argv[i++], "w");
156
h = fopen(argv[i++], "w");
157
if (fread(buffer, 1, 32, f) != 32) exit(1);
158
if (fread(buffer2, 1, 32, e) != 32) exit(1);
159
if (memcmp(buffer, buffer2, 32)) {
160
fprintf(stderr, "Strange. Images for 2.5MB and 3.5MB differ in a.out header\n");
165
memset (buffer, 0, 2048);
166
if (fwrite(buffer, 1, 2048, g) != 2048) exit(1);
168
if (fwrite (buffer, 1, 32, g) != 32) exit(1);
171
save (g, first_start, 0);
172
save (h, first_end - first_start, 2);
173
save (g, rodata_start - first_end, 0);
174
save (h, rodata_end - rodata_start, 2);
175
save (g, second_start - rodata_end, 0);
176
save (h, second_end - second_start, 2);
177
save (g, end - second_end, 0);
178
fwrite(diffs[0], 2, ndiffs[0]+1, g);
179
fwrite(diffs[1], 2, ndiffs[1]+1, g);
180
fwrite(diffs[2], 2, ndiffs[2]+1, h);
181
fwrite(diffs[3], 2, ndiffs[3]+1, h);