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.
27 #error "Compile error: struct exec invalid (long not 32 bit ?)"
30 unsigned long text_offt
[10]; /* Locations to patch (0=don't) */
31 unsigned long data_offt
[10];
33 char * input_file
= "";
42 long image_offset
, text_off
;
45 if( argc
< 3 || argc
> 11 )
46 fatal("Usage: catimage mem.bin boot.out [a1.out] ... [a9.out]");
50 ofd
= fopen(argv
[1], "w");
51 if( ofd
== 0 ) fatal("Cannot open output file");
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
);
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");
93 printf("Output file size %ldKb\n", ((image_offset
+0x3FF)>>10));
95 if( ifd
) fclose(ifd
);
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");
113 fatal("Input file has bad magic number");
116 copy_segment(out_offset
, in_offset
, length
)
117 long out_offset
, in_offset
, 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");
131 if( bsize
> sizeof(buffer
) ) ssize
= sizeof(buffer
);
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");
142 patch_bin(file_off
, value
)
147 if( file_off
<= 0 ) return;
149 printf("Patch at offset 0x%05lx = %04x\n", file_off
, 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");
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
;
176 while( fread(&item
, sizeof(struct nlist
), 1, ifd
) == 1 )
178 if( nitems
-- <= 0 ) break;
181 if( memcmp(item
.n_name
, "__seg", 5) != 0 || item
.n_name
[6] != '_' )
185 if( (item
.n_sclass
& N_CLASS
) != C_EXT
)
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
)
194 if( item
.n_name
[5] < '0' || item
.n_name
[5] > '9' )
197 if( (header
.a_flags
& A_SEP
) && (item
.n_sclass
& N_SECT
) != N_TEXT
)
198 base_off
= header
.a_text
;
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;
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;
235 fprintf(stderr
, "catimage:%s: %s\n", input_file
, str
);