Remove naked access to the data members in SectionEntry and route
accesses through accessor functions. This makes it obvious how the
instances of the class are used, and will also facilitate adding bounds
checking to advanceStubOffset in a later change.
Details
Diff Detail
Event Timeline
It seems like "Section.getAddress() + Offset" shows up pretty frequently. Do you think it's worth making a function to do that too?
Otherwise, this all looks pretty straightforward. All of my comments are about cleaning up things that exist in the current code.
lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp | ||
---|---|---|
860–861 | Is there a reason to keep the commented out debug code here? It should either be put inside a DEBUG() wrapper or deleted. | |
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | ||
449–451 | I know you didn't introduce them, but it would be nice to get rid of the C-style casts while you're making these changes. | |
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h | ||
303 | This cast is unnecessary. | |
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp | ||
303–304 | These variables should be changed to be uint8_t* and the processFDE function should be updated similarly. I know it's equivalent, but it would be better to be consistent. |
Thanks for the review!
About getAddress -- what do you think of an interface like
template<typename T = uint8_t> T* getAddress(size_t Offset = 0) { return static_cast<T *>(Address + Offset); }
? That'll let us get rid of of the casts, and also add some bounds checking to getAddress in D14675.
I'd prefer to see getAddressWithOffset(size_t Offset) as a separate function, but I do think it would be great to add bounds checking for this.
As for the template idea, you'd have to use reinterpret_cast to make the conversions used work, and I'd rather see the reinterpret_cast at the point of use so that it is obvious that such a heavy-handed cast is being used. Also, I think using a template in the offset case might make it unclear what's happening in a case like this (from the current code):
uint32_t *TargetPtr = reinterpret_cast<uint32_t *>(Section.getAddress() + Offset);
because this
uint32_t *TargetPtr = Section.getAddressWithOffset<uint32_t *>(Offset);
makes it ambigous as to whether the address is offset by Offset bytes or Offset uint32_t's.
I think this is easier to comprehend this way:
uint32_t *TargetPtr = reinterpret_cast<uint32_t*>(Section.getAddressWithOffset(Offset));
Even like that the function declaration will require a clear comment about what the offset parameter means.
Address review
- add getAddressWithOffset
- add getLoadAddressWithOffset
- other misc. review comments
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h | ||
---|---|---|
65 | Just noticed that there are some more of these left -- I'll upload a new diff fixing these shortly. |
- address review: get the remaining getAddress() + Offset --> getAddressWithOffset(Offset) cases
- bugfix: re-associate the expression for COFF::IMAGE_REL_I386_DIR32NB. This shows up (as a failed assert) after adding the bound checking code in the next change
Just a few more cases that could be cleaned up.
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | ||
---|---|---|
1282–1285 | C-style cast and could be getAddressWithOffset(Section.getStubOffset()) | |
1298 | C-style cast | |
1314–1317 | C-style cast and could be getAddressWithOffset(Section.getStubOffset()). | |
1481–1482 | C-style cast and could use getAddressWithOffset | |
1525 | C-style cast |
Is there a reason to keep the commented out debug code here? It should either be put inside a DEBUG() wrapper or deleted.