* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / ld / catimage.c
blob7d5c7a047927d3d64ba0941bcebc062e7344e47b
1 /*
2 * This program concatenates memory images the executables specified
3 * on it's command line.
5 * The 'boot' image must have a symbol table any symbols that match
6 * the below patterns have their values patched.
8 * int __seg0_text; - Always zero
9 * int __seg0_data; - Segment offset of data of boot executable
11 * int __seg1_text; - Segment offset of text of first executable
12 * int __seg1_data; - Segment offset of data of first executable
13 * int __seg2_text; - Segment offset of text of second executable
14 * int __seg2_data; - Segment offset of data of second executable
16 * int __seg9_text; - Segment offset of text of executable nine
17 * int __seg9_data; - Segment offset of data of executable nine
19 * Any segment that's not an exact multiple of 16 bytes long is rounded up.
23 #include <stdio.h>
24 #include "x86_aout.h"
26 #ifndef __OUT_OK
27 #error "Compile error: struct exec invalid (long not 32 bit ?)"
28 #endif
30 unsigned long text_offt[10]; /* Locations to patch (0=don't) */
31 unsigned long data_offt[10];
33 char * input_file = "";
34 FILE * ofd;
35 FILE * ifd = 0;
36 struct exec header;
38 main(argc, argv)
39 int argc;
40 char ** argv;
42 long image_offset, text_off;
43 int image_id;
45 if( argc < 3 || argc > 11 )
46 fatal("Usage: catimage mem.bin boot.out [a1.out] ... [a9.out]");
48 open_obj(argv[2]);
50 ofd = fopen(argv[1], "w");
51 if( ofd == 0 ) fatal("Cannot open output file");
53 read_symtable();
55 image_offset = 0;
57 for(image_id=0; image_id < argc-2; image_id++)
59 open_obj(argv[image_id+2]);
61 printf("File %-14s seg=0x%04lx text=0x%04lx data=0x%04lx\n",
62 input_file, (image_offset>>4),
63 (header.a_text>>4), (header.a_total>>4));
65 text_off = image_offset;
66 if( header.a_flags & A_SEP )
68 copy_segment(image_offset, A_TEXTPOS(header), header.a_text);
69 image_offset += header.a_text;
70 image_offset = ((image_offset+15L)&-16L);
72 copy_segment(image_offset, A_DATAPOS(header), header.a_data);
74 else
76 copy_segment(image_offset, A_TEXTPOS(header),
77 header.a_text+header.a_data);
80 patch_bin(text_offt[image_id], (unsigned)(text_off>>4));
81 patch_bin(data_offt[image_id], (unsigned)(image_offset>>4));
83 image_offset += header.a_total;
84 image_offset = ((image_offset+15L)&-16L);
87 if( fseek(ofd, image_offset-1, 0) < 0 )
88 fatal("Cannot seek to end of output");
90 fputc('\0', ofd);
91 fclose(ofd);
93 printf("Output file size %ldKb\n", ((image_offset+0x3FF)>>10));
95 if( ifd ) fclose(ifd);
96 exit(0);
99 open_obj(fname)
100 char * fname;
102 input_file = fname;
104 if( ifd ) fclose(ifd);
106 ifd = fopen(fname, "r");
107 if( ifd == 0 ) fatal("Cannot open input file");
109 if( fread(&header, A_MINHDR, 1, ifd) != 1 )
110 fatal("Incomplete executable header");
112 if( BADMAG(header) )
113 fatal("Input file has bad magic number");
116 copy_segment(out_offset, in_offset, length)
117 long out_offset, in_offset, length;
119 char buffer[1024];
120 int ssize;
121 long bsize = length;
123 if( fseek(ifd, in_offset, 0) < 0 )
124 fatal("Cannot seek to start of input segment");
126 if( fseek(ofd, out_offset, 0) < 0 )
127 fatal("Cannot seek to start of output segment");
129 while(bsize>0)
131 if( bsize > sizeof(buffer) ) ssize = sizeof(buffer);
132 else ssize = bsize;
134 if( (ssize=fread(buffer, 1, ssize, ifd)) <= 0 )
135 fatal("Error reading segment from executable");
136 if( fwrite(buffer, 1, ssize, ofd) != ssize )
137 fatal("Error writing output file");
138 bsize -= ssize;
142 patch_bin(file_off, value)
143 long file_off;
144 int value;
146 char wbuf[4];
147 if( file_off <= 0 ) return;
149 printf("Patch at offset 0x%05lx = %04x\n", file_off, value);
151 wbuf[0] = value;
152 wbuf[0] = (value>>8);
154 if( fseek(ofd, file_off, 0) < 0 )
155 fatal("Cannot seek to patch binary");
157 if( fwrite(wbuf, 1, 2, ofd) != 2 )
158 fatal("Error patching output file");
161 read_symtable()
163 struct nlist item;
164 int nitems;
165 long base_off = 0;
167 if( header.a_syms == 0 )
168 fatal("Input file has been stripped!");
170 if( fseek(ifd, A_SYMPOS(header), 0) < 0 )
171 fatal("Cannot seek to start of symbols");
173 nitems = header.a_syms;
175 /* Foreach symbol */
176 while( fread(&item, sizeof(struct nlist), 1, ifd) == 1 )
178 if( nitems-- <= 0 ) break;
180 /* Match the name */
181 if( memcmp(item.n_name, "__seg", 5) != 0 || item.n_name[6] != '_' )
182 continue;
184 /* Externals only */
185 if( (item.n_sclass & N_CLASS) != C_EXT )
186 continue;
188 /* Data seg only */
189 if( (item.n_sclass & N_SECT) != N_DATA &&
190 (item.n_sclass & N_SECT) != N_BSS &&
191 (item.n_sclass & N_SECT) != N_TEXT )
192 continue;
194 if( item.n_name[5] < '0' || item.n_name[5] > '9' )
195 continue;
197 if( (header.a_flags & A_SEP) && (item.n_sclass & N_SECT) != N_TEXT )
198 base_off = header.a_text;
199 else
200 base_off = 0;
202 switch( item.n_name[7] )
204 case 'd': data_offt[item.n_name[5]-'0'] = base_off+item.n_value; break;
205 case 't': text_offt[item.n_name[5]-'0'] = base_off+item.n_value; break;
208 #ifdef DEBUG
209 printf("%-8.8s ", item.n_name);
210 printf("%08lx ", item.n_value);
211 switch(item.n_sclass & N_CLASS)
213 case C_NULL: printf("C_NULL "); break;
214 case C_EXT: printf("C_EXT "); break;
215 case C_STAT: printf("C_STAT "); break;
216 default: printf("%-6d ", (item.n_sclass & N_CLASS)); break;
218 switch(item.n_sclass & N_SECT)
220 case N_UNDF: printf("N_UNDF "); break;
221 case N_ABS : printf("N_ABS "); break;
222 case N_TEXT: printf("N_TEXT "); break;
223 case N_DATA: printf("N_DATA "); break;
224 case N_BSS : printf("N_BSS "); break;
225 case N_COMM: printf("N_COMM "); break;
227 printf("\n");
228 #endif
232 fatal(str)
233 char * str;
235 fprintf(stderr, "catimage:%s: %s\n", input_file, str);
236 exit(2);