[llvm-objcopy][MachO] Fix MachO::relocation_info use after 386f1c114d.

Use shift/mask operations to access r_symbolnum rather than relying on
MachO::relocation_info. This should fix the big-endian bot failures that were
caused by 386f1c114d.
This commit is contained in:
Lang Hames 2020-04-16 18:21:41 -07:00
parent cbf99e0fba
commit cc0ec3fdb9
3 changed files with 25 additions and 9 deletions

View File

@ -204,10 +204,9 @@ void MachOReader::setSymbolInRelocationInfo(Object &O) const {
for (LoadCommand &LC : O.LoadCommands)
for (std::unique_ptr<Section> &Sec : LC.Sections)
for (auto &Reloc : Sec->Relocations)
if (!Reloc.Scattered) {
auto *Info = reinterpret_cast<MachO::relocation_info *>(&Reloc.Info);
Reloc.Symbol = O.SymTable.getSymbolByIndex(Info->r_symbolnum);
}
if (!Reloc.Scattered)
Reloc.Symbol = O.SymTable.getSymbolByIndex(
Reloc.getPlainRelocationSymbolNum(O.isLittleEndian()));
}
void MachOReader::readRebaseInfo(Object &O) const {

View File

@ -240,11 +240,9 @@ void MachOWriter::writeSections() {
Sec->Content.size());
for (size_t Index = 0; Index < Sec->Relocations.size(); ++Index) {
auto RelocInfo = Sec->Relocations[Index];
if (!RelocInfo.Scattered) {
auto *Info =
reinterpret_cast<MachO::relocation_info *>(&RelocInfo.Info);
Info->r_symbolnum = RelocInfo.Symbol->Index;
}
if (!RelocInfo.Scattered)
RelocInfo.setPlainRelocationSymbolNum(RelocInfo.Symbol->Index,
O.isLittleEndian());
if (IsLittleEndian != sys::IsLittleEndianHost)
MachO::swapStruct(

View File

@ -161,6 +161,20 @@ struct RelocationInfo {
// True if Info is a scattered_relocation_info.
bool Scattered;
MachO::any_relocation_info Info;
unsigned getPlainRelocationSymbolNum(bool IsLittleEndian) {
if (IsLittleEndian)
return Info.r_word1 & 0xffffff;
return Info.r_word1 >> 8;
}
void setPlainRelocationSymbolNum(unsigned SymbolNum, bool IsLittleEndian) {
assert(SymbolNum < (1 << 24) && "SymbolNum out of range");
if (IsLittleEndian)
Info.r_word1 = (Info.r_word1 & ~0x00ffffff) | SymbolNum;
else
Info.r_word1 = (Info.r_word1 & ~0xffffff00) | (SymbolNum << 8);
}
};
/// The location of the rebase info inside the binary is described by
@ -300,6 +314,11 @@ struct Object {
/// is not too long (SegName.size() should be less than or equal to 16).
LoadCommand &addSegment(StringRef SegName);
bool isLittleEndian() const {
StringRef Magic(reinterpret_cast<const char *>(&Header.Magic), 4);
return Magic == "\xCE\xFA\xED\xFE" || Magic == "\xCF\xFA\xED\xFE";
}
bool is64Bit() const {
return Header.Magic == MachO::MH_MAGIC_64 ||
Header.Magic == MachO::MH_CIGAM_64;