@@ -122,44 +122,72 @@ static bool needToRelocate(SectionRef S) {
122
122
123
123
124
124
class Image {
125
- std::vector<char > Memory;
125
+ const ObjectFile *O;
126
+ uint64_t VASize;
126
127
127
- public:
128
- explicit Image (const ObjectFile *O) {
129
- uint64_t VASize = O->getData ().size ();
130
- for (SectionRef S : O->sections ()) {
131
- if (auto SectionAddr = getSectionAddress (S))
132
- VASize = std::max (VASize, SectionAddr + S.getSize ());
133
- }
134
- Memory.resize (VASize);
135
- std::memcpy (&Memory[0 ], O->getData ().data (), O->getData ().size ());
128
+ struct RelocatedRegion {
129
+ uint64_t Start, Size;
130
+ const char *Base;
131
+ };
136
132
133
+ std::vector<RelocatedRegion> RelocatedRegions;
134
+
135
+ public:
136
+ explicit Image (const ObjectFile *O) : O(O), VASize(O->getData ().size()) {
137
137
for (SectionRef S : O->sections ()) {
138
138
if (!needToRelocate (S))
139
139
continue ;
140
140
StringRef Content;
141
+ auto SectionAddr = getSectionAddress (S);
142
+ if (SectionAddr)
143
+ VASize = std::max (VASize, SectionAddr + S.getSize ());
144
+
141
145
if (auto EC = S.getContents (Content))
142
146
reportError (EC);
143
- std::memcpy (&Memory[getSectionAddress (S)], Content.data (),
144
- Content.size ());
147
+
148
+ auto PhysOffset = (uintptr_t )Content.data () - (uintptr_t )O->getData ().data ();
149
+
150
+ if (PhysOffset == SectionAddr) {
151
+ continue ;
152
+ }
153
+
154
+ RelocatedRegions.push_back (RelocatedRegion{
155
+ SectionAddr,
156
+ Content.size (),
157
+ Content.data ()});
145
158
}
146
159
}
147
160
148
161
RemoteAddress getStartAddress () const {
149
- return RemoteAddress ((uintptr_t )Memory .data ());
162
+ return RemoteAddress ((uintptr_t )O-> getData () .data ());
150
163
}
151
164
152
165
bool isAddressValid (RemoteAddress Addr, uint64_t Size) const {
153
- return ( uintptr_t )Memory. data () <= Addr .getAddressData () &&
154
- Addr.getAddressData () + Size <=
155
- ( uintptr_t )Memory. data () + Memory. size () ;
166
+ auto start = getStartAddress () .getAddressData ();
167
+ return start <= Addr.getAddressData ()
168
+ && Addr. getAddressData () + Size <= start + VASize ;
156
169
}
157
170
158
171
ReadBytesResult readBytes (RemoteAddress Addr, uint64_t Size) {
159
172
if (!isAddressValid (Addr, Size))
160
173
return ReadBytesResult (nullptr , [](const void *) {});
161
- return ReadBytesResult ((const void *)(Addr.getAddressData ()),
162
- [](const void *) {});
174
+
175
+ auto addrValue = Addr.getAddressData ();
176
+ auto base = O->getData ().data ();
177
+ auto offset = addrValue - (uint64_t )base;
178
+ for (auto ®ion : RelocatedRegions) {
179
+ if (region.Start <= offset && offset < region.Start + region.Size ) {
180
+ // Read shouldn't need to straddle section boundaries.
181
+ if (offset + Size > region.Start + region.Size )
182
+ return ReadBytesResult (nullptr , [](const void *) {});
183
+
184
+ offset -= region.Start ;
185
+ base = region.Base ;
186
+ break ;
187
+ }
188
+ }
189
+
190
+ return ReadBytesResult (base + offset, [](const void *) {});
163
191
}
164
192
};
165
193
0 commit comments