I considered making a Target::validate() method, but I wasn't sure how I felt about the overhead of doing yet another switch-dispatch on the relocation type, so I put the validation in relocateOne instead... might be a bit of a micro-optimization, but relocateOne does assume certain things about the relocations it gets, and this error handling makes that explicit, so it's not a totally unreasonable code organization.
Depends on D80048.
Low-priority follow-up: be consistent about including or not including parameter names in all these declarations, both here and in the header.