1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 :(before "End Main")
23 if (is_equal(argv[1], "translate")) {
24 START_TRACING_UNTIL_END_OF_SCOPE;
25 assert(argc > 3);
26 program p;
27 ifstream fin(argv[2]);
28 if (!fin) {
29 cerr << "could not open " << argv[2] << '\n';
30 return 1;
31 }
32 parse(fin, p);
33 if (trace_contains_errors()) return 1;
34 transform(p);
35 if (trace_contains_errors()) return 1;
36 save_elf(p, argv[3]);
37 if (trace_contains_errors()) unlink(argv[3]);
38 return 0;
39 }
40
41 :(code)
42
43 void save_elf(const program& p, const char* filename) {
44 ofstream out(filename, ios::binary);
45 write_elf_header(out, p);
46 for (size_t i = 0; i < p.segments.size(); ++i)
47 write_segment(p.segments.at(i), out);
48 out.close();
49 }
50
51 void write_elf_header(ostream& out, const program& p) {
52 char c = '\0';
53
54
55
56
57
58 O(0x7f); O(0x45); O(0x4c); O(0x46);
59 O(0x1);
60 O(0x1);
61 O(0x1); O(0x0);
62 for (size_t i = 0; i < 8; ++i) { O(0x0); }
63
64 O(0x02); O(0x00);
65
66 O(0x03); O(0x00);
67
68 O(0x01); O(0x00); O(0x00); O(0x00);
69
70 int e_entry = p.segments.at(0).start;
71 emit(e_entry);
72
73 int e_phoff = 0x34;
74 emit(e_phoff);
75
76 int dummy32 = 0;
77 emit(dummy32);
78
79 emit(dummy32);
80
81 uint16_t e_ehsize = 0x34;
82 emit(e_ehsize);
83
84 uint16_t e_phentsize = 0x20;
85 emit(e_phentsize);
86
87 uint16_t e_phnum = SIZE(p.segments);
88 emit(e_phnum);
89
90 uint16_t dummy16 = 0x0;
91 emit(dummy16);
92
93 emit(dummy16);
94
95 emit(dummy16);
96
97 uint32_t p_offset = 0x34 + SIZE(p.segments)*0x20;
98 for (int i = 0; i < SIZE(p.segments); ++i) {
99
100
101 uint32_t p_type = 0x1;
102 emit(p_type);
103
104 emit(p_offset);
105
106 emit(p.segments.at(i).start);
107
108 emit(p.segments.at(i).start);
109
110 uint32_t size = size_of(p.segments.at(i));
111 assert(size < SEGMENT_SIZE);
112 emit(size);
113
114 emit(size);
115
116 uint32_t p_flags = (i == 0) ? 0x5 : 0x6;
117 emit(p_flags);
118
119
120
121
122
123
124
125
126
127
128
129
130 uint32_t p_align = 0x1000;
131 emit(p_align);
132 if (p_offset % p_align != p.segments.at(i).start % p_align) {
133 raise << "segment starting at 0x" << HEXWORD << p.segments.at(i).start << " is improperly aligned; alignment for p_offset " << p_offset << " should be " << (p_offset % p_align) << " but is " << (p.segments.at(i).start % p_align) << '\n' << end();
134 return;
135 }
136
137
138 p_offset += size;
139 }
140
141
142 }
143
144 void write_segment(const segment& s, ostream& out) {
145 for (int i = 0; i < SIZE(s.lines); ++i) {
146 const vector<word>& w = s.lines.at(i).words;
147 for (int j = 0; j < SIZE(w); ++j) {
148 uint8_t x = hex_byte(w.at(j).data);
149 out.write(reinterpret_cast<const char*>(&x), 1);
150 }
151 }
152 }
153
154 uint32_t size_of(const segment& s) {
155 uint32_t sum = 0;
156 for (int i = 0; i < SIZE(s.lines); ++i)
157 sum += SIZE(s.lines.at(i).words);
158 return sum;
159 }
160
161 :(before "End Includes")
162 using std::ios;