https://github.com/akkartik/mu/blob/master/subx/034compute_segment_address.cc
1
2
3
4
5
6
7
8
9 void test_segment_name() {
10 run(
11 "== code 0x09000000\n"
12 "05/add-to-EAX 0x0d0c0b0a/imm32\n"
13
14 );
15 CHECK_TRACE_CONTENTS(
16 "load: 0x09000054 -> 05\n"
17 "load: 0x09000055 -> 0a\n"
18 "load: 0x09000056 -> 0b\n"
19 "load: 0x09000057 -> 0c\n"
20 "load: 0x09000058 -> 0d\n"
21 "run: add imm32 0x0d0c0b0a to EAX\n"
22 "run: storing 0x0d0c0b0a\n"
23 );
24 }
25
26
27
28 :(before "End Level-2 Transforms")
29 Transform.push_back(compute_segment_starts);
30
31 :(code)
32 void compute_segment_starts(program& p) {
33 trace(3, "transform") << "-- compute segment addresses" << end();
34 uint32_t p_offset = 0x34 + SIZE(p.segments)*0x20;
35 for (size_t i = 0; i < p.segments.size(); ++i) {
36 segment& curr = p.segments.at(i);
37 if (curr.start >= 0x08000000) {
38
39 curr.start &= 0xfffff000;
40 curr.start |= p_offset;
41 trace(99, "transform") << "segment " << i << " begins at address 0x" << HEXWORD << curr.start << end();
42 }
43 p_offset += size_of(curr);
44 assert(p_offset < SEGMENT_ALIGNMENT);
45 }
46 }
47
48 uint32_t size_of(const segment& s) {
49 uint32_t sum = 0;
50 for (int i = 0; i < SIZE(s.lines); ++i)
51 sum += num_bytes(s.lines.at(i));
52 return sum;
53 }
54
55
56 uint32_t num_bytes(const line& inst) {
57 uint32_t sum = 0;
58 for (int i = 0; i < SIZE(inst.words); ++i)
59 sum += size_of(inst.words.at(i));
60 return sum;
61 }
62
63 int size_of(const word& w) {
64 if (has_operand_metadata(w, "disp32") || has_operand_metadata(w, "imm32"))
65 return 4;
66 else if (has_operand_metadata(w, "disp16"))
67 return 2;
68
69 else
70 return 1;
71 }
72
73
74
75