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