Skip to content

Commit cc0ec3f

Browse files
committed
[llvm-objcopy][MachO] Fix MachO::relocation_info use after 386f1c1.
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 386f1c1.
1 parent cbf99e0 commit cc0ec3f

File tree

3 files changed

+25
-9
lines changed

3 files changed

+25
-9
lines changed

llvm/tools/llvm-objcopy/MachO/MachOReader.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,9 @@ void MachOReader::setSymbolInRelocationInfo(Object &O) const {
204204
for (LoadCommand &LC : O.LoadCommands)
205205
for (std::unique_ptr<Section> &Sec : LC.Sections)
206206
for (auto &Reloc : Sec->Relocations)
207-
if (!Reloc.Scattered) {
208-
auto *Info = reinterpret_cast<MachO::relocation_info *>(&Reloc.Info);
209-
Reloc.Symbol = O.SymTable.getSymbolByIndex(Info->r_symbolnum);
210-
}
207+
if (!Reloc.Scattered)
208+
Reloc.Symbol = O.SymTable.getSymbolByIndex(
209+
Reloc.getPlainRelocationSymbolNum(O.isLittleEndian()));
211210
}
212211

213212
void MachOReader::readRebaseInfo(Object &O) const {

llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,9 @@ void MachOWriter::writeSections() {
240240
Sec->Content.size());
241241
for (size_t Index = 0; Index < Sec->Relocations.size(); ++Index) {
242242
auto RelocInfo = Sec->Relocations[Index];
243-
if (!RelocInfo.Scattered) {
244-
auto *Info =
245-
reinterpret_cast<MachO::relocation_info *>(&RelocInfo.Info);
246-
Info->r_symbolnum = RelocInfo.Symbol->Index;
247-
}
243+
if (!RelocInfo.Scattered)
244+
RelocInfo.setPlainRelocationSymbolNum(RelocInfo.Symbol->Index,
245+
O.isLittleEndian());
248246

249247
if (IsLittleEndian != sys::IsLittleEndianHost)
250248
MachO::swapStruct(

llvm/tools/llvm-objcopy/MachO/Object.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,20 @@ struct RelocationInfo {
161161
// True if Info is a scattered_relocation_info.
162162
bool Scattered;
163163
MachO::any_relocation_info Info;
164+
165+
unsigned getPlainRelocationSymbolNum(bool IsLittleEndian) {
166+
if (IsLittleEndian)
167+
return Info.r_word1 & 0xffffff;
168+
return Info.r_word1 >> 8;
169+
}
170+
171+
void setPlainRelocationSymbolNum(unsigned SymbolNum, bool IsLittleEndian) {
172+
assert(SymbolNum < (1 << 24) && "SymbolNum out of range");
173+
if (IsLittleEndian)
174+
Info.r_word1 = (Info.r_word1 & ~0x00ffffff) | SymbolNum;
175+
else
176+
Info.r_word1 = (Info.r_word1 & ~0xffffff00) | (SymbolNum << 8);
177+
}
164178
};
165179

166180
/// The ___location of the rebase info inside the binary is described by
@@ -300,6 +314,11 @@ struct Object {
300314
/// is not too long (SegName.size() should be less than or equal to 16).
301315
LoadCommand &addSegment(StringRef SegName);
302316

317+
bool isLittleEndian() const {
318+
StringRef Magic(reinterpret_cast<const char *>(&Header.Magic), 4);
319+
return Magic == "\xCE\xFA\xED\xFE" || Magic == "\xCF\xFA\xED\xFE";
320+
}
321+
303322
bool is64Bit() const {
304323
return Header.Magic == MachO::MH_MAGIC_64 ||
305324
Header.Magic == MachO::MH_CIGAM_64;

0 commit comments

Comments
 (0)