blob: f9a875784fa88582ea68a41c84105e0effe1c16d (
plain)
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
|
This is an implementation of the System.Diagnostics.SymbolStore.ISymbolWriter
interface which writes a symbol file in the dwarf format.
The output is an assembler input file containing dwarf data with an
additional ELF section called ".mono_reloc_table". This section is
read by the JIT engine to map IL offsets and such to machine
addresses.
The mono relocation table contains of
1. A 2-byte unsigned integer containing a version number, currently 2.
2. A 1-byte unsigned integer containing a flag specifying whether the
object file containing this section has already been relocated.
The symbol writer sets this flag to zero, you must change it to 1
if you write the relocated file back to disk.
3. A 4-byte unsigned integer containing the total size of the
relocation table, but not including the size field itself.
4. One or more relocation entries.
Each entry in the relocation table has the following form:
1. A 1-byte unsigned integer specifying the type of this entry.
2. A 4-byte unsigned integer containing the size of this entry, but
not including the size field itself.
3. A 1-byte unsigned integer specifying the ELF section of this entry.
4. A 4-byte unsigned offset from the beginning of the ELF section to
the location which needs to be relocated. This is called the target.
5. Optional additional data depending on the type of the entry.
The following entry types are currently defined:
a) TARGET_ADDRESS_SIZE - 0x01
The target is a 1-byte unsigned integer containing the size in
bytes of an address on the target machine.
b) IL_OFFSET - 0x02
The target is an integer of appropriate size to hold an address on
the target machine (the assembler ensures that the object has the
correct size) and contains an IL offset from the beginning of the
current method which needs to be replaced with the corresponding
machine address.
This entry has a 4-byte unsigned integer argument containing the
metadata token of the current method and a 4-byte unsigned integer
argument containing the IL offset.
c) METHOD_START_ADDRESS - 0x03
d) METHOD_END_ADDRESS - 0x04
The target is an integer of appropriate size to hold an address on
the target machine (the assembler ensures that the object has the
correct size).
This entry has a 4-byte unsigned integer argument containing the
metadata token of the current method.
To use the generated object file, the JIT must:
* Check whether the file contains a ".mono_reloc_table" section.
If not, the file cannot be used (you need to change the address size
field in each compilation unit header).
* Check whether the flag field of the relocation table (the 3rd byte
of the relocation table) is zero. If it is 1, the file has already
been relocated. In this case, it's best to reject the file.
* Set the flag field to 1.
* Process all relocation entries.
* Write the modified file back to disk.
To do the relocation, the JIT can assume that:
1.) All the relevant ELF sections are physically contiguous
(a requirement from the DWARF 2 specification).
2.) All relocation targets holding addresses are suitable of holding
an address on the target machine.
This means that you can do something like
* (void **) ptr = map_to_machine (* (void **) ptr)
3.) There are no other changes needed in the object file - so you can
just write it back to disk once you're done with the relocation.
Last changed March 19th, 2002
Martin Baulig <martin@gnome.org>
|