1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
#include "410kern/inc/exec2obj.h"
#include <stdio.h>
#include <string.h>
#define STABS 0
void print_usage() {
fprintf(stderr, "Usage: exec2obj <file>...\n");
fprintf(stderr, "Creates a .s file containing a const char array for each file\n");
fprintf(stderr, "given as an argument. Each array is initialized to the contents\n");
fprintf(stderr, "of that file. A table of contents is also created. Look at\n");
fprintf(stderr, "exec2obj.h for more information.\n\n");
}
char header[] =
#if STABS
"\t.file\t\"user_apps.c\"\n"
"\t.stabs\t\"/home/gghartma/15-410/proj2/\",100,0,0,.Ltext0\n"
"\t.stabs\t\"user_apps.c\",100,0,0,.Ltext0\n"
#endif
"\t.text\n"
".Ltext0:\n"
#if STABS
"\t.stabs\t\"gcc2_compiled.\",60,0,0,0\n"
"\t.stabs\t\"int:t(0,1)=r(0,1);-2147483648;2147483647;\",128,0,0,0\n"
"\t.stabs\t\"char:t(0,2)=r(0,2);0;127;\",128,0,0,0\n"
"\t.stabs\t\"long int:t(0,3)=r(0,3);-2147483648;2147483647;\",128,0,0,0\n"
"\t.stabs\t\"unsigned int:t(0,4)=r(0,4);0000000000000;0037777777777;\",128,0,0,0\n"
"\t.stabs\t\"long unsigned int:t(0,5)=r(0,5);0000000000000;0037777777777;\",128,0,0,0\n"
"\t.stabs\t\"long long int:t(0,6)=@s64;r(0,6);01000000000000000000000;0777777777777777777777;\",128,0,0,0\n"
"\t.stabs\t\"long long unsigned int:t(0,7)=@s64;r(0,7);0000000000000;01777777777777777777777;\",128,0,0,0\n"
"\t.stabs\t\"short int:t(0,8)=@s16;r(0,8);-32768;32767;\",128,0,0,0\n"
"\t.stabs\t\"short unsigned int:t(0,9)=@s16;r(0,9);0;65535;\",128,0,0,0\n"
"\t.stabs\t\"signed char:t(0,10)=@s8;r(0,10);-128;127;\",128,0,0,0\n"
"\t.stabs\t\"unsigned char:t(0,11)=@s8;r(0,11);0;255;\",128,0,0,0\n"
"\t.stabs\t\"float:t(0,12)=r(0,1);4;0;\",128,0,0,0\n"
"\t.stabs\t\"double:t(0,13)=r(0,1);8;0;\",128,0,0,0\n"
"\t.stabs\t\"long double:t(0,14)=r(0,1);12;0;\",128,0,0,0\n"
"\t.stabs\t\"complex int:t(0,15)=s8real:(0,1),0,32;imag:(0,1),32,32;;\",128,0,0,0\n"
"\t.stabs\t\"complex float:t(0,16)=R3;8;0;\",128,0,0,0\n"
"\t.stabs\t\"complex double:t(0,17)=R4;16;0;\",128,0,0,0\n"
"\t.stabs\t\"complex long double:t(0,18)=R5;24;0;\",128,0,0,0\n"
"\t.stabs\t\"void:t(0,19)=(0,19)\",128,0,0,0\n"
"\t.stabs\t\"__builtin_va_list:t(0,20)=*(0,2)\",128,0,0,0\n"
"\t.stabs\t\"_Bool:t(0,21)=@s8;-16\",128,0,0,0\n"
"\t.stabs\t\"user_apps.c\",130,0,0,0\n"
"\t.stabs\t\"410kern/lib/inc/exec2obj.h\",130,0,0,0\n"
"\t.stabs\t\"exec2obj_userapp_TOC_entry:t(2,1)=(2,2)=s264execname:(2,3)=ar(2,4)=r(2,4);0000000000000;0037777777777;;0;255;(2,5)=k(0,2),0,2048;execbytes:(2,6)=*(2,5),2048,32;execlen:(0,1),2080,32;;\",128,0,21,0\n"
"\t.stabn\t162,0,0,0\n"
#endif
"\t.section\t.rodata\n"
;
void emit_file_header(FILE *s, const char *file, int execsize)
{
fprintf(s,".globl %s_exec2obj_userapp_code_ptr\n", file);
fprintf(s,"\t.align 32\n");
fprintf(s,"\t.type\t%s_exec2obj_userapp_code_ptr, @object\n", file);
fprintf(s,"\t.size\t%s_exec2obj_userapp_code_ptr, %d\n", file, execsize);
fprintf(s,"%s_exec2obj_userapp_code_ptr:\n", file);
}
int emit_file_bytes(FILE *out, FILE *in, int bytes)
{
char line[1];
static const size_t sz = sizeof(line) / sizeof(line[0]);
while (1) {
size_t rval = fread(line, sizeof(line[0]), sz, in);
if (rval <= 0)
break;
bytes -= rval;
fprintf(out, "\t.byte\t%d", line[0]);
char *it = line + 1;
char *end = line + rval;
while (it != end) {
fprintf(out, ",%d", *it++);
}
fprintf(out, "\n");
}
return bytes;
}
void emit_dir_header(FILE *out, int nrfiles)
{
fprintf(out, ".globl exec2obj_userapp_count\n"
"\t.align 4\n"
"\t.type\texec2obj_userapp_count, @object\n"
"\t.size\texec2obj_userapp_count, 4\n"
"exec2obj_userapp_count:\n");
fprintf(out, "\t.long\t%d\n", nrfiles);
fprintf(out, ".globl exec2obj_userapp_TOC\n"
"\t.align 32\n"
"\t.type\texec2obj_userapp_TOC, @object\n");
fprintf(out, "\t.size\texec2obj_userapp_TOC, %d\n", sizeof(exec2obj_userapp_TOC));
fprintf(out, "exec2obj_userapp_TOC:\n");
}
void emit_dir_entry(FILE *out, const char *name, int size)
{
/* This is an awful hack, since we want the directory listing file
* named something that it can't be named on the host file system
* and can't appear in a symbol name. */
const char *listed_name =
(strcmp(name, "__DIR_LISTING__") == 0) ? "." : name;
fprintf(out, "\t.string\t\"%s\"\n", listed_name);
fprintf(out, "\t.zero\t%d\n", sizeof(exec2obj_userapp_TOC[0].execname) - strlen(listed_name) - 1);
fprintf(out, "\t.long\t%s_exec2obj_userapp_code_ptr\n", name);
fprintf(out, "\t.long\t%d\n", size);
}
void emit_dir_footer(FILE *out, int nrfiles)
{
fprintf(out, "\t.zero\t%d\n",
sizeof(exec2obj_userapp_TOC) - nrfiles * sizeof(exec2obj_userapp_TOC[0]));
fprintf(out,
#if STABS
"\t.stabs\t\"exec2obj_userapp_count:G(1,1)=k(0,1)\",32,0,8,0\n"
"\t.stabs\t\"exec2obj_userapp_TOC:G(1,2)=ar(2,4);0;127;(1,3)=k(2,1)\",32,0,9,0\n"
"\t.stabs\t\"idle_exec2obj_userapp_code_ptr:G(1,4)=ar(2,4);0;9574;(2,5)\",32,0,2,0\n"
"\t.stabs\t\"shell_exec2obj_userapp_code_ptr:G(1,5)=ar(2,4);0;39418;(2,5)\",32,0,4,0\n"
"\t.stabs\t\"init_exec2obj_userapp_code_ptr:G(1,6)=ar(2,4);0;21722;(2,5)\",32,0,6,0\n"
#endif
"\t.text\n"
#if STABS
"\t.stabs \"\",100,0,0,.Letext\n"
#endif
".Letext:\n"
#if STABS
"\t.section\t.note.GNU-stack,\"\",@progbits\n"
"\t.ident\t\"GCC: (GNU) 3.3.5 (Debian 1:3.3.5-13)\"\n"
#endif
);
}
#define MAX_FNAME 128
int main(int argc, char** argv) {
FILE *in;
int execsize = 0;
int file_iter = 1;
int execsizes[MAX_NUM_APP_ENTRIES];
char fname_buf[MAX_FNAME];
/* If there are no executables specified it's an error. */
if (argc < 2) {
print_usage();
return -1;
}
if (argc > MAX_NUM_APP_ENTRIES + 1) {
fprintf(stderr, "Too many executables: The maximum is %d\n", MAX_NUM_APP_ENTRIES);
}
fwrite(header, sizeof(header[0]), sizeof(header) / sizeof(header[0]) - 1, stdout);
while (file_iter < argc) {
strncpy(fname_buf, argv[file_iter], MAX_FNAME);
strncat(fname_buf, ".strip", MAX_FNAME - strlen(fname_buf));
in = fopen(fname_buf,"r");
if (!in) {
fprintf(stderr, "Could not open %s for reading; falling back.\n",fname_buf);
/* Open the executable. */
in = fopen(argv[file_iter],"r");
if (!in) {
fprintf(stderr, "Could not open %s for reading.\n",argv[file_iter]);
printf("\n\n.abort\n\n");
return -1;
}
}
/* Find size of executable. */
fseek(in,0,SEEK_END);
execsize = ftell(in);
fseek(in,0,SEEK_SET);
execsizes[file_iter] = execsize;
/* Output the header of the file. */
emit_file_header(stdout, argv[file_iter], execsize);
emit_file_bytes(stdout, in, execsize);
fclose(in);
/* Move on to the next file. */
file_iter++;
}
emit_dir_header(stdout, argc-1);
/* Output the table of contents. */
file_iter = 1;
/* Output all other entries in TOC. */
while(file_iter < argc) {
emit_dir_entry(stdout, argv[file_iter], execsizes[file_iter]);
file_iter++;
}
emit_dir_footer(stdout, argc-1);
return 0;
}
|