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
//! What COFF answers, where the two formats answer differently.
//!
//! Design: `spec/11-asm-objects-debug.md` section 11.3 and `spec/cross-compile/07-object-formats.md`
//! section 7.4. The sibling of [`crate::elf`], and the shape of a file is [`crate::file`]'s for both.
//!
//! # The relocation that counts from the other end
//!
//! Both formats write the distance from an instruction to something into four bytes, and they
//! disagree about where that distance is measured from. ELF counts from where the four bytes start
//! and lets the addend make up whatever else is wanted, so one relocation type covers every
//! instruction. COFF counts from where the instruction ends, which is not a number it can be told,
//! so it is in the relocation type instead: `IMAGE_REL_AMD64_REL32` is an instruction that ends at
//! the hole and `REL32_1` through `REL32_5` are one whose last one to five bytes come after it. That
//! is why [`crate::Reloc`] carries the count as well as the addend it is already inside.
//!
//! What is not here is anything about the addend, because the writer underneath does that part: it
//! reads the type, works out the same one to five, adds it to the addend it was handed and writes
//! the sum into the bytes, since a COFF relocation has no field to keep an addend in.
//!
//! # What this format has no answer for
//!
//! Three things, and each is refused by name rather than written as something close. A visibility is
//! the one that is not refused: `hidden` and `protected` are facts about a dynamic symbol table and
//! a COFF symbol has nowhere to put either, so a file built with `-fvisibility=hidden` for Windows
//! is a file where that flag changed nothing, which is what gcc does there too.
use RelocationFlags;
use pe;
use Object as Writer;
use Fixup;
use crateReference;
/// Which relocation of this machine one reference is, given how many bytes of the instruction come
/// after the four the linker writes over.
///
/// The first two are the distance to something and are the same relocation here, because a call to
/// a name in another image is answered by an import stub the linker makes whether or not the
/// relocation asked for one, which is the difference ELF spends a second type on. The last two are
/// the address itself at the two widths this machine writes one at.
///
/// Nothing for the two table slots. A global offset table is not how this platform reaches a symbol
/// it does not define, and a thread-local variable is reached through its offset in `.tls` instead,
/// so a file wanting either is a file this cannot write and says so.
///
/// The last is the one relocation here that ELF has nothing to match: four bytes holding how far
/// something is from the front of the image, which is what every field of an unwind table is.
pub
/// The same, as the writer underneath wants it.
pub
/// Which relocation of an AArch64 file one reference is.
///
/// A field of an instruction is the same field ELF names, less the table slots, which are not how
/// this platform reaches anything, and the offsets from the thread pointer, which this platform
/// reaches through the offset from the start of `.tls` instead. The literal load has nothing either:
/// the format has no nineteen bit distance to data, only to code, and gas and clang never ask for
/// one. The six loads and stores are one relocation here, since the linker reads how far to shift
/// the low bits from the instruction rather than from the type.
///
/// The distance written as data is `REL32`, which counts from the byte after the four it fills,
/// and the writer underneath adds the four back to the addend the way it does for the x86 types,
/// so the linker's answer is the distance from the hole that ELF gives.
pub
/// An instruction with the addend of its relocation written into the field the linker fills, or
/// why it cannot be.
///
/// A COFF relocation has no addend, so the number added to the name goes where the linker will
/// find it, which for data is the bytes being relocated and for an instruction is the field. The
/// writer underneath does the first and refuses the second, so this is the second. What each field
/// holds is what lld and link.exe read back out of it. The page `adrp` names is counted from the
/// name plus the whole addend, so its field is the addend in bytes, all twenty one bits of it. The
/// low twelve bits are added to the low twelve bits of the name, which gives the low twelve bits of
/// the sum whatever the addend is, carried or not, since what is carried out of them is the page's
/// business. A load or store keeps its twelve bits shifted by the size of the access, so the addend
/// has to be a multiple of that size, which it is for any field of a variable the access is of.
///
/// A branch is refused. Its field is combined with the distance in a way that has changed between
/// linkers, and a branch to a name plus a number is not something a compiler writes. The two halves
/// of an offset into `.tls` are refused too, because the high half is worked out from the name
/// alone and a carry out of the low half, which the addend can cause, would be lost between them.
pub
/// Nothing, which is what this format has for a variable the loader writes into before anything
/// reads it and the linker was asked to keep apart from the rest.
///
/// `.data.rel.ro` and the `.local` half of it are an ELF answer to a problem this format solves
/// elsewhere. A Windows image has its fixups applied before the pages are given the protection the
/// section headers asked for, so a pointer that needs one lives in ordinary read only data and is
/// written to anyway, which is where the linker and every other compiler on the platform put it.
pub const REL_RO_LOCAL: = None;
/// What the unwind table is called here, and what it is aligned to.
///
/// One fixed row per function, which the linker sorts by address so that the runtime can find the
/// row for a return address by binary search. Four, because a row is three four byte fields.
///
/// The name is the platform's and the linker matches on it, so it is not a choice: the directory
/// entry telling the runtime where the table is is built out of whatever landed in `.pdata`.
pub const FUNCTIONS: = ;
/// What the second half of the unwind table is called, and what it is aligned to.
///
/// What the rows point at, which is the description of each prologue. A second section rather than
/// more fields, because a row is a fixed size and a description is as long as the prologue it is
/// about.
pub const CODES: = ;
/// Nothing, which is what this format says about the stack being executable.
///
/// A PE image says whether its stack may be run from in the header of the image rather than in a
/// note in every input, so there is no marker for an object to carry and no linker looking for one.
pub