From f16c2bb320f4d5b33dfaf8df8865f547e6d66005 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 5 Apr 2013 15:15:22 +0000 Subject: Don't fetch pointers from a InMemoryStruct. InMemoryStruct is extremely dangerous as it returns data from an internal buffer when the endiannes doesn't match. This should fix the tests on big endian hosts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178875 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 6501df9fb9..9ab3599e2d 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -481,8 +481,7 @@ static StringRef parseSegmentOrSectionName(const char *P) { return StringRef(P, 16); } -error_code MachOObjectFile::getSectionName(DataRefImpl DRI, - StringRef &Result) const { +ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl DRI) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); unsigned SectionOffset = LCI.Offset + sizeof(macho::Segment64LoadCommand) + @@ -490,7 +489,7 @@ error_code MachOObjectFile::getSectionName(DataRefImpl DRI, StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section64)); const macho::Section64 *sec = reinterpret_cast(Data.data()); - Result = parseSegmentOrSectionName(sec->Name); + return ArrayRef(sec->Name, 16); } else { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); unsigned SectionOffset = LCI.Offset + sizeof(macho::SegmentLoadCommand) + @@ -498,13 +497,19 @@ error_code MachOObjectFile::getSectionName(DataRefImpl DRI, StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section)); const macho::Section *sec = reinterpret_cast(Data.data()); - Result = parseSegmentOrSectionName(sec->Name); + return ArrayRef(sec->Name, 16); } +} + +error_code MachOObjectFile::getSectionName(DataRefImpl DRI, + StringRef &Result) const { + ArrayRef Raw = getSectionRawName(DRI); + Result = parseSegmentOrSectionName(Raw.data()); return object_error::success; } -error_code MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec, - StringRef &Res) const { +ArrayRef +MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { if (is64BitLoadCommand(MachOObj.get(), Sec)) { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(Sec.d.a); unsigned SectionOffset = LCI.Offset + sizeof(macho::Segment64LoadCommand) + @@ -512,7 +517,7 @@ error_code MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec, StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section64)); const macho::Section64 *sec = reinterpret_cast(Data.data()); - Res = parseSegmentOrSectionName(sec->SegmentName); + return ArrayRef(sec->SegmentName, 16); } else { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(Sec.d.a); unsigned SectionOffset = LCI.Offset + sizeof(macho::SegmentLoadCommand) + @@ -520,9 +525,13 @@ error_code MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec, StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section)); const macho::Section *sec = reinterpret_cast(Data.data()); - Res = parseSegmentOrSectionName(sec->SegmentName); + return ArrayRef(sec->SegmentName); } - return object_error::success; +} + +StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const { + ArrayRef Raw = getSectionRawFinalSegmentName(DRI); + return parseSegmentOrSectionName(Raw.data()); } error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, -- cgit v1.2.3 From c1cd6aa7a485933fa1b451c8df899ae78382b391 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 5 Apr 2013 18:18:19 +0000 Subject: Don't use InMemoryStruct in getSection and getSection64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178894 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 137 +++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 86 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 9ab3599e2d..684a43b48b 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -138,8 +138,8 @@ error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, getSymbol64TableEntry(DRI, Entry); Result = Entry->Value; if (Entry->SectionIndex) { - InMemoryStruct Section; - getSection64(Sections[Entry->SectionIndex-1], Section); + const macho::Section64 *Section = + getSection64(Sections[Entry->SectionIndex-1]); Result += Section->Offset - Section->Address; } } else { @@ -147,8 +147,8 @@ error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, getSymbolTableEntry(DRI, Entry); Result = Entry->Value; if (Entry->SectionIndex) { - InMemoryStruct Section; - getSection(Sections[Entry->SectionIndex-1], Section); + const macho::Section *Section = + getSection(Sections[Entry->SectionIndex-1]); Result += Section->Offset - Section->Address; } } @@ -444,11 +444,21 @@ error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, return object_error::success; } -void -MachOObjectFile::getSection(DataRefImpl DRI, - InMemoryStruct &Res) const { +static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - MachOObj->ReadSection(LCI, DRI.d.b, Res); + if (LCI.Command.Type == macho::LCT_Segment64) + return true; + assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type."); + return false; +} + +const macho::Section *MachOObjectFile::getSection(DataRefImpl DRI) const { + assert(!is64BitLoadCommand(MachOObj.get(), DRI)); + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + unsigned SectionOffset = LCI.Offset + sizeof(macho::SegmentLoadCommand) + + DRI.d.b * sizeof(macho::Section); + StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section)); + return reinterpret_cast(Data.data()); } std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { @@ -458,19 +468,14 @@ std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { return std::distance(Sections.begin(), loc); } -void -MachOObjectFile::getSection64(DataRefImpl DRI, - InMemoryStruct &Res) const { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - MachOObj->ReadSection64(LCI, DRI.d.b, Res); -} - -static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { +const macho::Section64 * +MachOObjectFile::getSection64(DataRefImpl DRI) const { + assert(is64BitLoadCommand(MachOObj.get(), DRI)); LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - if (LCI.Command.Type == macho::LCT_Segment64) - return true; - assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type."); - return false; + unsigned SectionOffset = LCI.Offset + sizeof(macho::Segment64LoadCommand) + + DRI.d.b * sizeof(macho::Section64); + StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section64)); + return reinterpret_cast(Data.data()); } static StringRef parseSegmentOrSectionName(const char *P) { @@ -483,21 +488,11 @@ static StringRef parseSegmentOrSectionName(const char *P) { ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl DRI) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - unsigned SectionOffset = LCI.Offset + sizeof(macho::Segment64LoadCommand) + - DRI.d.b * sizeof(macho::Section64); - StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section64)); - const macho::Section64 *sec = - reinterpret_cast(Data.data()); - return ArrayRef(sec->Name, 16); + const macho::Section64 *sec = getSection64(DRI); + return ArrayRef(sec->Name); } else { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - unsigned SectionOffset = LCI.Offset + sizeof(macho::SegmentLoadCommand) + - DRI.d.b * sizeof(macho::Section); - StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section)); - const macho::Section *sec = - reinterpret_cast(Data.data()); - return ArrayRef(sec->Name, 16); + const macho::Section *sec = getSection(DRI); + return ArrayRef(sec->Name); } } @@ -511,20 +506,10 @@ error_code MachOObjectFile::getSectionName(DataRefImpl DRI, ArrayRef MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { if (is64BitLoadCommand(MachOObj.get(), Sec)) { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(Sec.d.a); - unsigned SectionOffset = LCI.Offset + sizeof(macho::Segment64LoadCommand) + - Sec.d.b * sizeof(macho::Section64); - StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section64)); - const macho::Section64 *sec = - reinterpret_cast(Data.data()); + const macho::Section64 *sec = getSection64(Sec); return ArrayRef(sec->SegmentName, 16); } else { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(Sec.d.a); - unsigned SectionOffset = LCI.Offset + sizeof(macho::SegmentLoadCommand) + - Sec.d.b * sizeof(macho::Section); - StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section)); - const macho::Section *sec = - reinterpret_cast(Data.data()); + const macho::Section *sec = getSection(Sec); return ArrayRef(sec->SegmentName); } } @@ -537,12 +522,10 @@ StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const { error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, uint64_t &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - InMemoryStruct Sect; - getSection64(DRI, Sect); + const macho::Section64 *Sect = getSection64(DRI); Result = Sect->Address; } else { - InMemoryStruct Sect; - getSection(DRI, Sect); + const macho::Section *Sect = getSection(DRI); Result = Sect->Address; } return object_error::success; @@ -551,12 +534,10 @@ error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, uint64_t &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - InMemoryStruct Sect; - getSection64(DRI, Sect); + const macho::Section64 *Sect = getSection64(DRI); Result = Sect->Size; } else { - InMemoryStruct Sect; - getSection(DRI, Sect); + const macho::Section *Sect = getSection(DRI); Result = Sect->Size; } return object_error::success; @@ -565,12 +546,10 @@ error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, StringRef &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - InMemoryStruct Sect; - getSection64(DRI, Sect); + const macho::Section64 *Sect = getSection64(DRI); Result = MachOObj->getData(Sect->Offset, Sect->Size); } else { - InMemoryStruct Sect; - getSection(DRI, Sect); + const macho::Section *Sect = getSection(DRI); Result = MachOObj->getData(Sect->Offset, Sect->Size); } return object_error::success; @@ -579,12 +558,10 @@ error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, uint64_t &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - InMemoryStruct Sect; - getSection64(DRI, Sect); + const macho::Section64 *Sect = getSection64(DRI); Result = uint64_t(1) << Sect->Align; } else { - InMemoryStruct Sect; - getSection(DRI, Sect); + const macho::Section *Sect = getSection(DRI); Result = uint64_t(1) << Sect->Align; } return object_error::success; @@ -593,12 +570,10 @@ error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, error_code MachOObjectFile::isSectionText(DataRefImpl DRI, bool &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - InMemoryStruct Sect; - getSection64(DRI, Sect); + const macho::Section64 *Sect = getSection64(DRI); Result = Sect->Flags & macho::SF_PureInstructions; } else { - InMemoryStruct Sect; - getSection(DRI, Sect); + const macho::Section *Sect = getSection(DRI); Result = Sect->Flags & macho::SF_PureInstructions; } return object_error::success; @@ -635,14 +610,12 @@ error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI, bool &Result) const { if (MachOObj->is64Bit()) { - InMemoryStruct Sect; - getSection64(DRI, Sect); + const macho::Section64 *Sect = getSection64(DRI); unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; Result = (SectionType == MachO::SectionTypeZeroFill || SectionType == MachO::SectionTypeZeroFillLarge); } else { - InMemoryStruct Sect; - getSection(DRI, Sect); + const macho::Section *Sect = getSection(DRI); unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; Result = (SectionType == MachO::SectionTypeZeroFill || SectionType == MachO::SectionTypeZeroFillLarge); @@ -700,12 +673,10 @@ relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { uint32_t last_reloc; if (is64BitLoadCommand(MachOObj.get(), Sec)) { - InMemoryStruct Sect; - getSection64(Sec, Sect); + const macho::Section64 *Sect = getSection64(Sec); last_reloc = Sect->NumRelocationTableEntries; } else { - InMemoryStruct Sect; - getSection(Sec, Sect); + const macho::Section *Sect = getSection(Sec); last_reloc = Sect->NumRelocationTableEntries; } DataRefImpl ret; @@ -733,12 +704,10 @@ getRelocation(DataRefImpl Rel, InMemoryStruct &Res) const { uint32_t relOffset; if (MachOObj->is64Bit()) { - InMemoryStruct Sect; - getSection64(Sections[Rel.d.b], Sect); + const macho::Section64 *Sect = getSection64(Sections[Rel.d.b]); relOffset = Sect->RelocationTableOffset; } else { - InMemoryStruct Sect; - getSection(Sections[Rel.d.b], Sect); + const macho::Section *Sect = getSection(Sections[Rel.d.b]); relOffset = Sect->RelocationTableOffset; } MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res); @@ -753,12 +722,10 @@ error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { const uint8_t* sectAddress = 0; if (MachOObj->is64Bit()) { - InMemoryStruct Sect; - getSection64(Sections[Rel.d.b], Sect); + const macho::Section64 *Sect = getSection64(Sections[Rel.d.b]); sectAddress += Sect->Address; } else { - InMemoryStruct Sect; - getSection(Sections[Rel.d.b], Sect); + const macho::Section *Sect = getSection(Sections[Rel.d.b]); sectAddress += Sect->Address; } InMemoryStruct RE; @@ -928,12 +895,10 @@ error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, if (!isExtern) { const uint8_t* sectAddress = base(); if (MachOObj->is64Bit()) { - InMemoryStruct Sect; - getSection64(Sections[Rel.d.b], Sect); + const macho::Section64 *Sect = getSection64(Sections[Rel.d.b]); sectAddress += Sect->Offset; } else { - InMemoryStruct Sect; - getSection(Sections[Rel.d.b], Sect); + const macho::Section *Sect = getSection(Sections[Rel.d.b]); sectAddress += Sect->Offset; } Res = reinterpret_cast(sectAddress); -- cgit v1.2.3 From 0e5dc8aacb548d51b0ca9035a7d449a8e5862dd2 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 5 Apr 2013 18:45:28 +0000 Subject: Define versions of Section that are explicitly marked as little endian. These should really be templated like ELF, but this is a start. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178896 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 68 +++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 684a43b48b..7de5462dd3 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -138,7 +138,7 @@ error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, getSymbol64TableEntry(DRI, Entry); Result = Entry->Value; if (Entry->SectionIndex) { - const macho::Section64 *Section = + const MachOFormat::Section64 *Section = getSection64(Sections[Entry->SectionIndex-1]); Result += Section->Offset - Section->Address; } @@ -147,7 +147,7 @@ error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, getSymbolTableEntry(DRI, Entry); Result = Entry->Value; if (Entry->SectionIndex) { - const macho::Section *Section = + const MachOFormat::Section *Section = getSection(Sections[Entry->SectionIndex-1]); Result += Section->Offset - Section->Address; } @@ -452,13 +452,13 @@ static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { return false; } -const macho::Section *MachOObjectFile::getSection(DataRefImpl DRI) const { +const MachOFormat::Section *MachOObjectFile::getSection(DataRefImpl DRI) const { assert(!is64BitLoadCommand(MachOObj.get(), DRI)); LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); unsigned SectionOffset = LCI.Offset + sizeof(macho::SegmentLoadCommand) + - DRI.d.b * sizeof(macho::Section); - StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section)); - return reinterpret_cast(Data.data()); + DRI.d.b * sizeof(MachOFormat::Section); + StringRef Data = MachOObj->getData(SectionOffset, sizeof(MachOFormat::Section)); + return reinterpret_cast(Data.data()); } std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { @@ -468,14 +468,14 @@ std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { return std::distance(Sections.begin(), loc); } -const macho::Section64 * +const MachOFormat::Section64 * MachOObjectFile::getSection64(DataRefImpl DRI) const { assert(is64BitLoadCommand(MachOObj.get(), DRI)); LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); unsigned SectionOffset = LCI.Offset + sizeof(macho::Segment64LoadCommand) + - DRI.d.b * sizeof(macho::Section64); - StringRef Data = MachOObj->getData(SectionOffset, sizeof(macho::Section64)); - return reinterpret_cast(Data.data()); + DRI.d.b * sizeof(MachOFormat::Section64); + StringRef Data = MachOObj->getData(SectionOffset, sizeof(MachOFormat::Section64)); + return reinterpret_cast(Data.data()); } static StringRef parseSegmentOrSectionName(const char *P) { @@ -488,10 +488,10 @@ static StringRef parseSegmentOrSectionName(const char *P) { ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl DRI) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - const macho::Section64 *sec = getSection64(DRI); + const MachOFormat::Section64 *sec = getSection64(DRI); return ArrayRef(sec->Name); } else { - const macho::Section *sec = getSection(DRI); + const MachOFormat::Section *sec = getSection(DRI); return ArrayRef(sec->Name); } } @@ -506,10 +506,10 @@ error_code MachOObjectFile::getSectionName(DataRefImpl DRI, ArrayRef MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { if (is64BitLoadCommand(MachOObj.get(), Sec)) { - const macho::Section64 *sec = getSection64(Sec); + const MachOFormat::Section64 *sec = getSection64(Sec); return ArrayRef(sec->SegmentName, 16); } else { - const macho::Section *sec = getSection(Sec); + const MachOFormat::Section *sec = getSection(Sec); return ArrayRef(sec->SegmentName); } } @@ -522,10 +522,10 @@ StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const { error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, uint64_t &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - const macho::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section64 *Sect = getSection64(DRI); Result = Sect->Address; } else { - const macho::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = Sect->Address; } return object_error::success; @@ -534,10 +534,10 @@ error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, uint64_t &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - const macho::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section64 *Sect = getSection64(DRI); Result = Sect->Size; } else { - const macho::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = Sect->Size; } return object_error::success; @@ -546,10 +546,10 @@ error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, StringRef &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - const macho::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section64 *Sect = getSection64(DRI); Result = MachOObj->getData(Sect->Offset, Sect->Size); } else { - const macho::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = MachOObj->getData(Sect->Offset, Sect->Size); } return object_error::success; @@ -558,10 +558,10 @@ error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, uint64_t &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - const macho::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section64 *Sect = getSection64(DRI); Result = uint64_t(1) << Sect->Align; } else { - const macho::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = uint64_t(1) << Sect->Align; } return object_error::success; @@ -570,10 +570,10 @@ error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, error_code MachOObjectFile::isSectionText(DataRefImpl DRI, bool &Result) const { if (is64BitLoadCommand(MachOObj.get(), DRI)) { - const macho::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section64 *Sect = getSection64(DRI); Result = Sect->Flags & macho::SF_PureInstructions; } else { - const macho::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = Sect->Flags & macho::SF_PureInstructions; } return object_error::success; @@ -610,12 +610,12 @@ error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI, bool &Result) const { if (MachOObj->is64Bit()) { - const macho::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section64 *Sect = getSection64(DRI); unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; Result = (SectionType == MachO::SectionTypeZeroFill || SectionType == MachO::SectionTypeZeroFillLarge); } else { - const macho::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; Result = (SectionType == MachO::SectionTypeZeroFill || SectionType == MachO::SectionTypeZeroFillLarge); @@ -673,10 +673,10 @@ relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { uint32_t last_reloc; if (is64BitLoadCommand(MachOObj.get(), Sec)) { - const macho::Section64 *Sect = getSection64(Sec); + const MachOFormat::Section64 *Sect = getSection64(Sec); last_reloc = Sect->NumRelocationTableEntries; } else { - const macho::Section *Sect = getSection(Sec); + const MachOFormat::Section *Sect = getSection(Sec); last_reloc = Sect->NumRelocationTableEntries; } DataRefImpl ret; @@ -704,10 +704,10 @@ getRelocation(DataRefImpl Rel, InMemoryStruct &Res) const { uint32_t relOffset; if (MachOObj->is64Bit()) { - const macho::Section64 *Sect = getSection64(Sections[Rel.d.b]); + const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); relOffset = Sect->RelocationTableOffset; } else { - const macho::Section *Sect = getSection(Sections[Rel.d.b]); + const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); relOffset = Sect->RelocationTableOffset; } MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res); @@ -722,10 +722,10 @@ error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { const uint8_t* sectAddress = 0; if (MachOObj->is64Bit()) { - const macho::Section64 *Sect = getSection64(Sections[Rel.d.b]); + const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); sectAddress += Sect->Address; } else { - const macho::Section *Sect = getSection(Sections[Rel.d.b]); + const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); sectAddress += Sect->Address; } InMemoryStruct RE; @@ -895,10 +895,10 @@ error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, if (!isExtern) { const uint8_t* sectAddress = base(); if (MachOObj->is64Bit()) { - const macho::Section64 *Sect = getSection64(Sections[Rel.d.b]); + const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); sectAddress += Sect->Offset; } else { - const macho::Section *Sect = getSection(Sections[Rel.d.b]); + const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); sectAddress += Sect->Offset; } Res = reinterpret_cast(sectAddress); -- cgit v1.2.3 From 5cf0f51ae6530751eeeccefa55c87f1d3422d0ae Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 6 Apr 2013 01:24:11 +0000 Subject: Don't use InMemoryStruct in getRelocation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178943 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 52 +++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 7de5462dd3..b7255d3e40 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -699,9 +699,8 @@ section_iterator MachOObjectFile::end_sections() const { /*===-- Relocations -------------------------------------------------------===*/ -void MachOObjectFile:: -getRelocation(DataRefImpl Rel, - InMemoryStruct &Res) const { +const MachOFormat::RelocationEntry * +MachOObjectFile::getRelocation(DataRefImpl Rel) const { uint32_t relOffset; if (MachOObj->is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); @@ -710,8 +709,12 @@ getRelocation(DataRefImpl Rel, const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); relOffset = Sect->RelocationTableOffset; } - MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res); + uint64_t Offset = relOffset + Rel.d.a * sizeof(MachOFormat::RelocationEntry); + StringRef Data = + MachOObj->getData(Offset, sizeof(MachOFormat::RelocationEntry)); + return reinterpret_cast(Data.data()); } + error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, RelocationRef &Res) const { ++Rel.d.a; @@ -728,8 +731,7 @@ error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); sectAddress += Sect->Address; } - InMemoryStruct RE; - getRelocation(Rel, RE); + const MachOFormat::RelocationEntry *RE = getRelocation(Rel); unsigned Arch = getArch(); bool isScattered = (Arch != Triple::x86_64) && @@ -745,8 +747,7 @@ error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, } error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const { - InMemoryStruct RE; - getRelocation(Rel, RE); + const MachOFormat::RelocationEntry *RE = getRelocation(Rel); unsigned Arch = getArch(); bool isScattered = (Arch != Triple::x86_64) && @@ -759,8 +760,7 @@ error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, } error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const { - InMemoryStruct RE; - getRelocation(Rel, RE); + const MachOFormat::RelocationEntry *RE = getRelocation(Rel); uint32_t SymbolIdx = RE->Word1 & 0xffffff; bool isExtern = (RE->Word1 >> 27) & 1; @@ -779,8 +779,7 @@ error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, } error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, uint64_t &Res) const { - InMemoryStruct RE; - getRelocation(Rel, RE); + const MachOFormat::RelocationEntry *RE = getRelocation(Rel); Res = RE->Word0; Res <<= 32; Res |= RE->Word1; @@ -790,8 +789,7 @@ error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl &Result) const { // TODO: Support scattered relocations. StringRef res; - InMemoryStruct RE; - getRelocation(Rel, RE); + const MachOFormat::RelocationEntry *RE = getRelocation(Rel); unsigned Arch = getArch(); bool isScattered = (Arch != Triple::x86_64) && @@ -888,8 +886,7 @@ error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, } error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, int64_t &Res) const { - InMemoryStruct RE; - getRelocation(Rel, RE); + const MachOFormat::RelocationEntry *RE = getRelocation(Rel); bool isExtern = (RE->Word1 >> 27) & 1; Res = 0; if (!isExtern) { @@ -923,7 +920,7 @@ void advanceTo(T &it, size_t Val) { } void MachOObjectFile::printRelocationTargetName( - InMemoryStruct& RE, + const MachOFormat::RelocationEntry *RE, raw_string_ostream &fmt) const { unsigned Arch = getArch(); bool isScattered = (Arch != Triple::x86_64) && @@ -994,8 +991,7 @@ void MachOObjectFile::printRelocationTargetName( error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, SmallVectorImpl &Result) const { - InMemoryStruct RE; - getRelocation(Rel, RE); + const MachOFormat::RelocationEntry *RE = getRelocation(Rel); unsigned Arch = getArch(); bool isScattered = (Arch != Triple::x86_64) && @@ -1032,10 +1028,9 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, break; } case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR - InMemoryStruct RENext; DataRefImpl RelNext = Rel; RelNext.d.a++; - getRelocation(RelNext, RENext); + const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext); // X86_64_SUBTRACTOR must be followed by a relocation of type // X86_64_RELOC_UNSIGNED. @@ -1080,10 +1075,9 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info return object_error::success; case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF - InMemoryStruct RENext; DataRefImpl RelNext = Rel; RelNext.d.a++; - getRelocation(RelNext, RENext); + const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext); // X86 sect diff's must be followed by a relocation of type // GENERIC_RELOC_PAIR. @@ -1110,10 +1104,9 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, // handled in the generic code. switch (Type) { case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF - InMemoryStruct RENext; DataRefImpl RelNext = Rel; RelNext.d.a++; - getRelocation(RelNext, RENext); + const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext); // X86 sect diff's must be followed by a relocation of type // GENERIC_RELOC_PAIR. @@ -1160,10 +1153,9 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, fmt << ":lower16:("; printRelocationTargetName(RE, fmt); - InMemoryStruct RENext; DataRefImpl RelNext = Rel; RelNext.d.a++; - getRelocation(RelNext, RENext); + const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext); // ARM half relocs must be followed by a relocation of type // ARM_RELOC_PAIR. @@ -1209,8 +1201,7 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const { - InMemoryStruct RE; - getRelocation(Rel, RE); + const MachOFormat::RelocationEntry *RE = getRelocation(Rel); unsigned Arch = getArch(); bool isScattered = (Arch != Triple::x86_64) && @@ -1233,8 +1224,7 @@ error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel, if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) { DataRefImpl RelPrev = Rel; RelPrev.d.a--; - InMemoryStruct REPrev; - getRelocation(RelPrev, REPrev); + const MachOFormat::RelocationEntry *REPrev = getRelocation(RelPrev); unsigned PrevType = (REPrev->Word1 >> 28) & 0xF; -- cgit v1.2.3 From 00555c13be54b7933cf5a68b50f8a7494bcd5777 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 6 Apr 2013 01:59:05 +0000 Subject: Don't use InMemoryStruct in getSymbolTableEntry. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178945 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index b7255d3e40..f82ed08250 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -78,8 +78,8 @@ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { } } -void MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, - InMemoryStruct &Res) const { +const MachOFormat::SymbolTableEntry * +MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { InMemoryStruct SymtabLoadCmd; LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); @@ -89,8 +89,13 @@ void MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, RegisteredStringTable = DRI.d.a; } - MachOObj->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, - Res); + uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; + unsigned Index = DRI.d.b; + uint64_t Offset = (SymbolTableOffset + + Index * sizeof(macho::SymbolTableEntry)); + StringRef Data = MachOObj->getData(Offset, + sizeof(MachOFormat::SymbolTableEntry)); + return reinterpret_cast(Data.data()); } void MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI, @@ -124,8 +129,7 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, getSymbol64TableEntry(DRI, Entry); Result = MachOObj->getStringAtIndex(Entry->StringIndex); } else { - InMemoryStruct Entry; - getSymbolTableEntry(DRI, Entry); + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); Result = MachOObj->getStringAtIndex(Entry->StringIndex); } return object_error::success; @@ -143,8 +147,7 @@ error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, Result += Section->Offset - Section->Address; } } else { - InMemoryStruct Entry; - getSymbolTableEntry(DRI, Entry); + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); Result = Entry->Value; if (Entry->SectionIndex) { const MachOFormat::Section *Section = @@ -163,8 +166,7 @@ error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, getSymbol64TableEntry(DRI, Entry); Result = Entry->Value; } else { - InMemoryStruct Entry; - getSymbolTableEntry(DRI, Entry); + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); Result = Entry->Value; } return object_error::success; @@ -205,8 +207,7 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, DRI.d.b++; } } else { - InMemoryStruct Entry; - getSymbolTableEntry(DRI, Entry); + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); BeginOffset = Entry->Value; SectionIndex = Entry->SectionIndex; if (!SectionIndex) { @@ -225,7 +226,7 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, while (Command == DRI.d.a) { moveToNextSymbol(DRI); if (DRI.d.a < LoadCommandCount) { - getSymbolTableEntry(DRI, Entry); + Entry = getSymbolTableEntry(DRI); if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset) if (!EndOffset || Entry->Value < EndOffset) EndOffset = Entry->Value; @@ -252,8 +253,7 @@ error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, Type = Entry->Type; Flags = Entry->Flags; } else { - InMemoryStruct Entry; - getSymbolTableEntry(DRI, Entry); + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); Type = Entry->Type; Flags = Entry->Flags; } @@ -288,8 +288,7 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, MachOFlags = Entry->Flags; MachOType = Entry->Type; } else { - InMemoryStruct Entry; - getSymbolTableEntry(DRI, Entry); + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); MachOFlags = Entry->Flags; MachOType = Entry->Type; } @@ -326,8 +325,7 @@ error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, getSymbol64TableEntry(Symb, Entry); index = Entry->SectionIndex; } else { - InMemoryStruct Entry; - getSymbolTableEntry(Symb, Entry); + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(Symb); index = Entry->SectionIndex; } @@ -347,8 +345,7 @@ error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, getSymbol64TableEntry(Symb, Entry); n_type = Entry->Type; } else { - InMemoryStruct Entry; - getSymbolTableEntry(Symb, Entry); + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(Symb); n_type = Entry->Type; } Res = SymbolRef::ST_Other; @@ -656,8 +653,7 @@ error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, uint64_t SymAddr= Entry->Value; Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); } else { - InMemoryStruct Entry; - getSymbolTableEntry(Symb, Entry); + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(Symb); uint64_t SymAddr= Entry->Value; Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); } -- cgit v1.2.3 From 05b5bdd024d07e7a62f1cdc39f465e10ce5dbc6d Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 6 Apr 2013 02:15:44 +0000 Subject: Don't use InMemoryStruct in getSymbol64TableEntry. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178946 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 43 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index f82ed08250..4d9186490f 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -98,8 +98,8 @@ MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { return reinterpret_cast(Data.data()); } -void MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI, - InMemoryStruct &Res) const { +const MachOFormat::Symbol64TableEntry* +MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { InMemoryStruct SymtabLoadCmd; LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); @@ -109,11 +109,15 @@ void MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI, RegisteredStringTable = DRI.d.a; } - MachOObj->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, - Res); + uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; + unsigned Index = DRI.d.b; + uint64_t Offset = (SymbolTableOffset + + Index * sizeof(macho::Symbol64TableEntry)); + StringRef Data = MachOObj->getData(Offset, + sizeof(MachOFormat::Symbol64TableEntry)); + return reinterpret_cast(Data.data()); } - error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, SymbolRef &Result) const { DRI.d.b++; @@ -125,8 +129,7 @@ error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, StringRef &Result) const { if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(DRI, Entry); + const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); Result = MachOObj->getStringAtIndex(Entry->StringIndex); } else { const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); @@ -138,8 +141,7 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, uint64_t &Result) const { if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(DRI, Entry); + const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); Result = Entry->Value; if (Entry->SectionIndex) { const MachOFormat::Section64 *Section = @@ -162,8 +164,7 @@ error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, uint64_t &Result) const { if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(DRI, Entry); + const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); Result = Entry->Value; } else { const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); @@ -179,8 +180,7 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, uint64_t EndOffset = 0; uint8_t SectionIndex; if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(DRI, Entry); + const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); BeginOffset = Entry->Value; SectionIndex = Entry->SectionIndex; if (!SectionIndex) { @@ -199,7 +199,7 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, while (Command == DRI.d.a) { moveToNextSymbol(DRI); if (DRI.d.a < LoadCommandCount) { - getSymbol64TableEntry(DRI, Entry); + Entry = getSymbol64TableEntry(DRI); if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset) if (!EndOffset || Entry->Value < EndOffset) EndOffset = Entry->Value; @@ -248,8 +248,7 @@ error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, char &Result) const { uint8_t Type, Flags; if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(DRI, Entry); + const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); Type = Entry->Type; Flags = Entry->Flags; } else { @@ -283,8 +282,7 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, uint16_t MachOFlags; uint8_t MachOType; if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(DRI, Entry); + const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); MachOFlags = Entry->Flags; MachOType = Entry->Type; } else { @@ -321,8 +319,7 @@ error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, section_iterator &Res) const { uint8_t index; if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(Symb, Entry); + const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(Symb); index = Entry->SectionIndex; } else { const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(Symb); @@ -341,8 +338,7 @@ error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const { uint8_t n_type; if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(Symb, Entry); + const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(Symb); n_type = Entry->Type; } else { const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(Symb); @@ -648,8 +644,7 @@ error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, SectEnd += SectBegin; if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(Symb, Entry); + const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(Symb); uint64_t SymAddr= Entry->Value; Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); } else { -- cgit v1.2.3 From 82a21077a004087a87711bfd7a4ab171cebaa5ec Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 6 Apr 2013 03:31:08 +0000 Subject: Don't use InMemoryStruct. This also required not using the RegisterStringTable API, which is also a good thing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178947 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 63 ++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 20 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 4d9186490f..e2b0468b9a 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -30,8 +30,7 @@ namespace object { MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, error_code &ec) : ObjectFile(Binary::ID_MachO, Object, ec), - MachOObj(MOO), - RegisteredStringTable(std::numeric_limits::max()) { + MachOObj(MOO) { DataRefImpl DRI; moveToNextSection(DRI); uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; @@ -62,13 +61,20 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { /*===-- Symbols -----------------------------------------------------------===*/ +const MachOFormat::SymtabLoadCommand * +MachOObjectFile::getSymtabLoadCommand(LoadCommandInfo LCI) const { + StringRef Data = MachOObj->getData(LCI.Offset, + sizeof(MachOFormat::SymtabLoadCommand)); + return reinterpret_cast(Data.data()); +} + void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); if (LCI.Command.Type == macho::LCT_Symtab) { - InMemoryStruct SymtabLoadCmd; - MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); + const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = + getSymtabLoadCommand(LCI); if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries) return; } @@ -80,15 +86,16 @@ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { const MachOFormat::SymbolTableEntry * MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { - InMemoryStruct SymtabLoadCmd; LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); + const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = + getSymtabLoadCommand(LCI); - if (RegisteredStringTable != DRI.d.a) { - MachOObj->RegisterStringTable(*SymtabLoadCmd); - RegisteredStringTable = DRI.d.a; - } + return getSymbolTableEntry(DRI, SymtabLoadCmd); +} +const MachOFormat::SymbolTableEntry * +MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, + const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const { uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; unsigned Index = DRI.d.b; uint64_t Offset = (SymbolTableOffset + @@ -100,15 +107,16 @@ MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { const MachOFormat::Symbol64TableEntry* MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { - InMemoryStruct SymtabLoadCmd; LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); + const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = + getSymtabLoadCommand(LCI); - if (RegisteredStringTable != DRI.d.a) { - MachOObj->RegisterStringTable(*SymtabLoadCmd); - RegisteredStringTable = DRI.d.a; - } + return getSymbol64TableEntry(DRI, SymtabLoadCmd); +} +const MachOFormat::Symbol64TableEntry* +MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI, + const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const { uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; unsigned Index = DRI.d.b; uint64_t Offset = (SymbolTableOffset + @@ -128,13 +136,28 @@ error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, StringRef &Result) const { + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = + getSymtabLoadCommand(LCI); + + StringRef StringTable = + MachOObj->getData(SymtabLoadCmd->StringTableOffset, + SymtabLoadCmd->StringTableSize); + + uint32_t StringIndex; if (MachOObj->is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); - Result = MachOObj->getStringAtIndex(Entry->StringIndex); + const MachOFormat::Symbol64TableEntry *Entry = + getSymbol64TableEntry(DRI, SymtabLoadCmd); + StringIndex = Entry->StringIndex; } else { - const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); - Result = MachOObj->getStringAtIndex(Entry->StringIndex); + const MachOFormat::SymbolTableEntry *Entry = + getSymbolTableEntry(DRI, SymtabLoadCmd); + StringIndex = Entry->StringIndex; } + + const char *Start = &StringTable.data()[StringIndex]; + Result = StringRef(Start); + return object_error::success; } -- cgit v1.2.3 From 68d287d19e6918f46e58456fdd237c049efe372e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 6 Apr 2013 03:50:05 +0000 Subject: Remove last use of InMemoryStruct from MachOObjectFile.cpp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178948 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index e2b0468b9a..1eb14f31ff 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -68,6 +68,21 @@ MachOObjectFile::getSymtabLoadCommand(LoadCommandInfo LCI) const { return reinterpret_cast(Data.data()); } +const MachOFormat::SegmentLoadCommand * +MachOObjectFile::getSegmentLoadCommand(LoadCommandInfo LCI) const { + StringRef Data = MachOObj->getData(LCI.Offset, + sizeof(MachOFormat::SegmentLoadCommand)); + return reinterpret_cast(Data.data()); +} + +const MachOFormat::Segment64LoadCommand * +MachOObjectFile::getSegment64LoadCommand(LoadCommandInfo LCI) const { + StringRef Data = MachOObj->getData(LCI.Offset, + sizeof(MachOFormat::Segment64LoadCommand)); + return + reinterpret_cast(Data.data()); +} + void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { @@ -436,13 +451,13 @@ void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { while (DRI.d.a < LoadCommandCount) { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); if (LCI.Command.Type == macho::LCT_Segment) { - InMemoryStruct SegmentLoadCmd; - MachOObj->ReadSegmentLoadCommand(LCI, SegmentLoadCmd); + const MachOFormat::SegmentLoadCommand *SegmentLoadCmd = + getSegmentLoadCommand(LCI); if (DRI.d.b < SegmentLoadCmd->NumSections) return; } else if (LCI.Command.Type == macho::LCT_Segment64) { - InMemoryStruct Segment64LoadCmd; - MachOObj->ReadSegment64LoadCommand(LCI, Segment64LoadCmd); + const MachOFormat::Segment64LoadCommand *Segment64LoadCmd = + getSegment64LoadCommand(LCI); if (DRI.d.b < Segment64LoadCmd->NumSections) return; } -- cgit v1.2.3 From 196abbffe9b7a760593d68b99cbb5f961efc8e2a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 14:40:18 +0000 Subject: Remove last use of InMemoryStruct in llvm-objdump. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178979 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 1eb14f31ff..94827693e9 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -75,6 +75,14 @@ MachOObjectFile::getSegmentLoadCommand(LoadCommandInfo LCI) const { return reinterpret_cast(Data.data()); } +const MachOFormat::LinkeditDataLoadCommand * +MachOObjectFile::getLinkeditDataLoadCommand(LoadCommandInfo LCI) const { + StringRef Data = MachOObj->getData(LCI.Offset, + sizeof(MachOFormat::LinkeditDataLoadCommand)); + return + reinterpret_cast(Data.data()); +} + const MachOFormat::Segment64LoadCommand * MachOObjectFile::getSegment64LoadCommand(LoadCommandInfo LCI) const { StringRef Data = MachOObj->getData(LCI.Offset, -- cgit v1.2.3 From 0be4eafd9c90d5e584b951fe2970f024341486c3 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 15:46:05 +0000 Subject: Remove two uses of getObject. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178985 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 94827693e9..86677231c4 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -41,6 +41,9 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, } } +bool MachOObjectFile::is64Bit() const { + return MachOObj->is64Bit(); +} ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { error_code ec; -- cgit v1.2.3 From 3eff318cbac281d46e8c8dfef16ffccbceebc855 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 16:07:35 +0000 Subject: Remove MachOObjectFile::getObject. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178986 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 86677231c4..fdce21bfd7 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -45,6 +45,20 @@ bool MachOObjectFile::is64Bit() const { return MachOObj->is64Bit(); } +const LoadCommandInfo & +MachOObjectFile::getLoadCommandInfo(unsigned Index) const { + return MachOObj->getLoadCommandInfo(Index); +} + +void MachOObjectFile::ReadULEB128s(uint64_t Index, + SmallVectorImpl &Out) const { + return MachOObj->ReadULEB128s(Index, Out); +} + +const macho::Header &MachOObjectFile::getHeader() const { + return MachOObj->getHeader(); +} + ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { error_code ec; std::string Err; -- cgit v1.2.3 From 2c6f997290f589b80da903e33718175666557dd7 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 16:40:00 +0000 Subject: Remove unused argument. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178987 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index fdce21bfd7..6f888faf9c 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -29,7 +29,7 @@ namespace object { MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, error_code &ec) - : ObjectFile(Binary::ID_MachO, Object, ec), + : ObjectFile(Binary::ID_MachO, Object), MachOObj(MOO) { DataRefImpl DRI; moveToNextSection(DRI); -- cgit v1.2.3 From 6f1f33915a09a862fd83e7c9f1dc465c2b9e427c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 16:58:48 +0000 Subject: Construct MachOObject in MachOObjectFile's constructor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178988 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 6f888faf9c..c817942ca1 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -27,10 +27,23 @@ using namespace object; namespace llvm { namespace object { -MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, - error_code &ec) - : ObjectFile(Binary::ID_MachO, Object), - MachOObj(MOO) { +MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, error_code &ec) + : ObjectFile(Binary::ID_MachO, Object) { + // MachOObject takes ownership of the Buffer we passed to it, and + // MachOObjectFile does, too, so we need to make sure they don't get the + // same object. A MemoryBuffer is cheap (it's just a reference to memory, + // not a copy of the memory itself), so just make a new copy here for + // the MachOObjectFile. + MemoryBuffer *NewBuffer = + MemoryBuffer::getMemBuffer(Object->getBuffer(), + Object->getBufferIdentifier(), false); + std::string ErrorStr; + MachOObj.reset(MachOObject::LoadFromBuffer(NewBuffer, &ErrorStr)); + if (!MachOObj) { + ec = object_error::parse_failed; + return; + } + DataRefImpl DRI; moveToNextSection(DRI); uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; @@ -61,19 +74,10 @@ const macho::Header &MachOObjectFile::getHeader() const { ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { error_code ec; - std::string Err; - MachOObject *MachOObj = MachOObject::LoadFromBuffer(Buffer, &Err); - if (!MachOObj) + ObjectFile *Ret = new MachOObjectFile(Buffer, ec); + if (ec) return NULL; - // MachOObject takes ownership of the Buffer we passed to it, and - // MachOObjectFile does, too, so we need to make sure they don't get the - // same object. A MemoryBuffer is cheap (it's just a reference to memory, - // not a copy of the memory itself), so just make a new copy here for - // the MachOObjectFile. - MemoryBuffer *NewBuffer = - MemoryBuffer::getMemBuffer(Buffer->getBuffer(), - Buffer->getBufferIdentifier(), false); - return new MachOObjectFile(NewBuffer, MachOObj, ec); + return Ret; } /*===-- Symbols -----------------------------------------------------------===*/ -- cgit v1.2.3 From f305127f0b46d0782f53c8aeab448f9dfeb769ec Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 17:41:59 +0000 Subject: Use getLoadCommandInfo instead of MachOObj->getLoadCommandInfo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178989 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index c817942ca1..e20ca2b353 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -115,7 +115,7 @@ MachOObjectFile::getSegment64LoadCommand(LoadCommandInfo LCI) const { void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); if (LCI.Command.Type == macho::LCT_Symtab) { const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = getSymtabLoadCommand(LCI); @@ -130,7 +130,7 @@ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { const MachOFormat::SymbolTableEntry * MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = getSymtabLoadCommand(LCI); @@ -151,7 +151,7 @@ MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, const MachOFormat::Symbol64TableEntry* MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = getSymtabLoadCommand(LCI); @@ -180,7 +180,7 @@ error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, StringRef &Result) const { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = getSymtabLoadCommand(LCI); @@ -478,7 +478,7 @@ StringRef MachOObjectFile::getLoadName() const { void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); if (LCI.Command.Type == macho::LCT_Segment) { const MachOFormat::SegmentLoadCommand *SegmentLoadCmd = getSegmentLoadCommand(LCI); @@ -504,7 +504,8 @@ error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, return object_error::success; } -static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { +static bool is64BitLoadCommand(const MachOObjectFile *MachOObj, + DataRefImpl DRI) { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); if (LCI.Command.Type == macho::LCT_Segment64) return true; @@ -513,8 +514,8 @@ static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { } const MachOFormat::Section *MachOObjectFile::getSection(DataRefImpl DRI) const { - assert(!is64BitLoadCommand(MachOObj.get(), DRI)); - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + assert(!is64BitLoadCommand(this, DRI)); + LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); unsigned SectionOffset = LCI.Offset + sizeof(macho::SegmentLoadCommand) + DRI.d.b * sizeof(MachOFormat::Section); StringRef Data = MachOObj->getData(SectionOffset, sizeof(MachOFormat::Section)); @@ -530,8 +531,8 @@ std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { const MachOFormat::Section64 * MachOObjectFile::getSection64(DataRefImpl DRI) const { - assert(is64BitLoadCommand(MachOObj.get(), DRI)); - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + assert(is64BitLoadCommand(this, DRI)); + LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); unsigned SectionOffset = LCI.Offset + sizeof(macho::Segment64LoadCommand) + DRI.d.b * sizeof(MachOFormat::Section64); StringRef Data = MachOObj->getData(SectionOffset, sizeof(MachOFormat::Section64)); @@ -547,7 +548,7 @@ static StringRef parseSegmentOrSectionName(const char *P) { } ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl DRI) const { - if (is64BitLoadCommand(MachOObj.get(), DRI)) { + if (is64BitLoadCommand(this, DRI)) { const MachOFormat::Section64 *sec = getSection64(DRI); return ArrayRef(sec->Name); } else { @@ -565,7 +566,7 @@ error_code MachOObjectFile::getSectionName(DataRefImpl DRI, ArrayRef MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { - if (is64BitLoadCommand(MachOObj.get(), Sec)) { + if (is64BitLoadCommand(this, Sec)) { const MachOFormat::Section64 *sec = getSection64(Sec); return ArrayRef(sec->SegmentName, 16); } else { @@ -581,7 +582,7 @@ StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const { error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, uint64_t &Result) const { - if (is64BitLoadCommand(MachOObj.get(), DRI)) { + if (is64BitLoadCommand(this, DRI)) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = Sect->Address; } else { @@ -593,7 +594,7 @@ error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, uint64_t &Result) const { - if (is64BitLoadCommand(MachOObj.get(), DRI)) { + if (is64BitLoadCommand(this, DRI)) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = Sect->Size; } else { @@ -605,7 +606,7 @@ error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, StringRef &Result) const { - if (is64BitLoadCommand(MachOObj.get(), DRI)) { + if (is64BitLoadCommand(this, DRI)) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = MachOObj->getData(Sect->Offset, Sect->Size); } else { @@ -617,7 +618,7 @@ error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, uint64_t &Result) const { - if (is64BitLoadCommand(MachOObj.get(), DRI)) { + if (is64BitLoadCommand(this, DRI)) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = uint64_t(1) << Sect->Align; } else { @@ -629,7 +630,7 @@ error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, error_code MachOObjectFile::isSectionText(DataRefImpl DRI, bool &Result) const { - if (is64BitLoadCommand(MachOObj.get(), DRI)) { + if (is64BitLoadCommand(this, DRI)) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = Sect->Flags & macho::SF_PureInstructions; } else { @@ -730,7 +731,7 @@ relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { } relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { uint32_t last_reloc; - if (is64BitLoadCommand(MachOObj.get(), Sec)) { + if (is64BitLoadCommand(this, Sec)) { const MachOFormat::Section64 *Sect = getSection64(Sec); last_reloc = Sect->NumRelocationTableEntries; } else { -- cgit v1.2.3 From 77638d9110d67333e4ea8e6bd3206606a89bc24f Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 18:08:12 +0000 Subject: Add MachOObjectFile::LoadCommandInfo. This avoids using MachOObject::getLoadCommandInfo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178990 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index e20ca2b353..dbbc812d14 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -58,9 +58,23 @@ bool MachOObjectFile::is64Bit() const { return MachOObj->is64Bit(); } -const LoadCommandInfo & +MachOObjectFile::LoadCommandInfo MachOObjectFile::getLoadCommandInfo(unsigned Index) const { - return MachOObj->getLoadCommandInfo(Index); + uint64_t Offset; + uint64_t NewOffset = MachOObj->getHeaderSize(); + const MachOFormat::LoadCommand *Load; + unsigned I = 0; + do { + Offset = NewOffset; + StringRef Data = MachOObj->getData(Offset, + sizeof(MachOFormat::LoadCommand)); + Load = reinterpret_cast(Data.data()); + NewOffset = Offset + Load->Size; + ++I; + } while (I != Index + 1); + + LoadCommandInfo Ret = {Load, Offset}; + return Ret; } void MachOObjectFile::ReadULEB128s(uint64_t Index, @@ -116,7 +130,7 @@ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); - if (LCI.Command.Type == macho::LCT_Symtab) { + if (LCI.Command->Type == macho::LCT_Symtab) { const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = getSymtabLoadCommand(LCI); if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries) @@ -479,12 +493,12 @@ void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); - if (LCI.Command.Type == macho::LCT_Segment) { + if (LCI.Command->Type == macho::LCT_Segment) { const MachOFormat::SegmentLoadCommand *SegmentLoadCmd = getSegmentLoadCommand(LCI); if (DRI.d.b < SegmentLoadCmd->NumSections) return; - } else if (LCI.Command.Type == macho::LCT_Segment64) { + } else if (LCI.Command->Type == macho::LCT_Segment64) { const MachOFormat::Segment64LoadCommand *Segment64LoadCmd = getSegment64LoadCommand(LCI); if (DRI.d.b < Segment64LoadCmd->NumSections) @@ -506,10 +520,11 @@ error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, static bool is64BitLoadCommand(const MachOObjectFile *MachOObj, DataRefImpl DRI) { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - if (LCI.Command.Type == macho::LCT_Segment64) + MachOObjectFile::LoadCommandInfo LCI = + MachOObj->getLoadCommandInfo(DRI.d.a); + if (LCI.Command->Type == macho::LCT_Segment64) return true; - assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type."); + assert(LCI.Command->Type == macho::LCT_Segment && "Unexpected Type."); return false; } -- cgit v1.2.3 From 6ab85a81d711b1e9d3bbc02e05812e7f867a7c40 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 18:42:06 +0000 Subject: Remove LoadCommandInfo now that we always have a pointer to the command. LoadCommandInfo was needed to keep a command and its offset in the file. Now that we always have a pointer to the command, we don't need the offset. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178991 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 85 ++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 58 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index dbbc812d14..002a98cbe6 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -58,7 +58,7 @@ bool MachOObjectFile::is64Bit() const { return MachOObj->is64Bit(); } -MachOObjectFile::LoadCommandInfo +const MachOFormat::LoadCommand * MachOObjectFile::getLoadCommandInfo(unsigned Index) const { uint64_t Offset; uint64_t NewOffset = MachOObj->getHeaderSize(); @@ -73,8 +73,7 @@ MachOObjectFile::getLoadCommandInfo(unsigned Index) const { ++I; } while (I != Index + 1); - LoadCommandInfo Ret = {Load, Offset}; - return Ret; + return Load; } void MachOObjectFile::ReadULEB128s(uint64_t Index, @@ -96,43 +95,13 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { /*===-- Symbols -----------------------------------------------------------===*/ -const MachOFormat::SymtabLoadCommand * -MachOObjectFile::getSymtabLoadCommand(LoadCommandInfo LCI) const { - StringRef Data = MachOObj->getData(LCI.Offset, - sizeof(MachOFormat::SymtabLoadCommand)); - return reinterpret_cast(Data.data()); -} - -const MachOFormat::SegmentLoadCommand * -MachOObjectFile::getSegmentLoadCommand(LoadCommandInfo LCI) const { - StringRef Data = MachOObj->getData(LCI.Offset, - sizeof(MachOFormat::SegmentLoadCommand)); - return reinterpret_cast(Data.data()); -} - -const MachOFormat::LinkeditDataLoadCommand * -MachOObjectFile::getLinkeditDataLoadCommand(LoadCommandInfo LCI) const { - StringRef Data = MachOObj->getData(LCI.Offset, - sizeof(MachOFormat::LinkeditDataLoadCommand)); - return - reinterpret_cast(Data.data()); -} - -const MachOFormat::Segment64LoadCommand * -MachOObjectFile::getSegment64LoadCommand(LoadCommandInfo LCI) const { - StringRef Data = MachOObj->getData(LCI.Offset, - sizeof(MachOFormat::Segment64LoadCommand)); - return - reinterpret_cast(Data.data()); -} - void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { - LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); - if (LCI.Command->Type == macho::LCT_Symtab) { + const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + if (Command->Type == macho::LCT_Symtab) { const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - getSymtabLoadCommand(LCI); + reinterpret_cast(Command); if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries) return; } @@ -144,9 +113,9 @@ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { const MachOFormat::SymbolTableEntry * MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { - LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); + const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - getSymtabLoadCommand(LCI); + reinterpret_cast(Command); return getSymbolTableEntry(DRI, SymtabLoadCmd); } @@ -165,9 +134,9 @@ MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, const MachOFormat::Symbol64TableEntry* MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { - LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); + const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - getSymtabLoadCommand(LCI); + reinterpret_cast(Command); return getSymbol64TableEntry(DRI, SymtabLoadCmd); } @@ -194,9 +163,9 @@ error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, StringRef &Result) const { - LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); + const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - getSymtabLoadCommand(LCI); + reinterpret_cast(Command); StringRef StringTable = MachOObj->getData(SymtabLoadCmd->StringTableOffset, @@ -492,15 +461,15 @@ StringRef MachOObjectFile::getLoadName() const { void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { - LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); - if (LCI.Command->Type == macho::LCT_Segment) { + const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + if (Command->Type == macho::LCT_Segment) { const MachOFormat::SegmentLoadCommand *SegmentLoadCmd = - getSegmentLoadCommand(LCI); + reinterpret_cast(Command); if (DRI.d.b < SegmentLoadCmd->NumSections) return; - } else if (LCI.Command->Type == macho::LCT_Segment64) { + } else if (Command->Type == macho::LCT_Segment64) { const MachOFormat::Segment64LoadCommand *Segment64LoadCmd = - getSegment64LoadCommand(LCI); + reinterpret_cast(Command); if (DRI.d.b < Segment64LoadCmd->NumSections) return; } @@ -520,21 +489,21 @@ error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, static bool is64BitLoadCommand(const MachOObjectFile *MachOObj, DataRefImpl DRI) { - MachOObjectFile::LoadCommandInfo LCI = + const MachOFormat::LoadCommand *Command = MachOObj->getLoadCommandInfo(DRI.d.a); - if (LCI.Command->Type == macho::LCT_Segment64) + if (Command->Type == macho::LCT_Segment64) return true; - assert(LCI.Command->Type == macho::LCT_Segment && "Unexpected Type."); + assert(Command->Type == macho::LCT_Segment && "Unexpected Type."); return false; } const MachOFormat::Section *MachOObjectFile::getSection(DataRefImpl DRI) const { assert(!is64BitLoadCommand(this, DRI)); - LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); - unsigned SectionOffset = LCI.Offset + sizeof(macho::SegmentLoadCommand) + + const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + uintptr_t CommandAddr = reinterpret_cast(Command); + uintptr_t SectionAddr = CommandAddr + sizeof(macho::SegmentLoadCommand) + DRI.d.b * sizeof(MachOFormat::Section); - StringRef Data = MachOObj->getData(SectionOffset, sizeof(MachOFormat::Section)); - return reinterpret_cast(Data.data()); + return reinterpret_cast(SectionAddr); } std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { @@ -547,11 +516,11 @@ std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { const MachOFormat::Section64 * MachOObjectFile::getSection64(DataRefImpl DRI) const { assert(is64BitLoadCommand(this, DRI)); - LoadCommandInfo LCI = getLoadCommandInfo(DRI.d.a); - unsigned SectionOffset = LCI.Offset + sizeof(macho::Segment64LoadCommand) + + const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + uintptr_t CommandAddr = reinterpret_cast(Command); + uintptr_t SectionAddr = CommandAddr + sizeof(macho::Segment64LoadCommand) + DRI.d.b * sizeof(MachOFormat::Section64); - StringRef Data = MachOObj->getData(SectionOffset, sizeof(MachOFormat::Section64)); - return reinterpret_cast(Data.data()); + return reinterpret_cast(SectionAddr); } static StringRef parseSegmentOrSectionName(const char *P) { -- cgit v1.2.3 From 0f08eb135997a94ba37f79aaeb306993c21bbae2 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 19:05:30 +0000 Subject: Implement MachOObjectFile::getHeaderSize and MachOObjectFile::getData. These were the last missing forwarding functions. Also consistently use the forwarding functions instead of using MachOObj directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178992 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 85 ++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 41 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 002a98cbe6..f011da1e3a 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -46,7 +46,7 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, error_code &ec) DataRefImpl DRI; moveToNextSection(DRI); - uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; + uint32_t LoadCommandCount = getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { Sections.push_back(DRI); DRI.d.b++; @@ -61,13 +61,12 @@ bool MachOObjectFile::is64Bit() const { const MachOFormat::LoadCommand * MachOObjectFile::getLoadCommandInfo(unsigned Index) const { uint64_t Offset; - uint64_t NewOffset = MachOObj->getHeaderSize(); + uint64_t NewOffset = getHeaderSize(); const MachOFormat::LoadCommand *Load; unsigned I = 0; do { Offset = NewOffset; - StringRef Data = MachOObj->getData(Offset, - sizeof(MachOFormat::LoadCommand)); + StringRef Data = getData(Offset, sizeof(MachOFormat::LoadCommand)); Load = reinterpret_cast(Data.data()); NewOffset = Offset + Load->Size; ++I; @@ -85,6 +84,14 @@ const macho::Header &MachOObjectFile::getHeader() const { return MachOObj->getHeader(); } +unsigned MachOObjectFile::getHeaderSize() const { + return MachOObj->getHeaderSize(); +} + +StringRef MachOObjectFile::getData(size_t Offset, size_t Size) const { + return MachOObj->getData(Offset, Size); +} + ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { error_code ec; ObjectFile *Ret = new MachOObjectFile(Buffer, ec); @@ -96,7 +103,7 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { /*===-- Symbols -----------------------------------------------------------===*/ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { - uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; + uint32_t LoadCommandCount = getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); if (Command->Type == macho::LCT_Symtab) { @@ -127,8 +134,7 @@ MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, unsigned Index = DRI.d.b; uint64_t Offset = (SymbolTableOffset + Index * sizeof(macho::SymbolTableEntry)); - StringRef Data = MachOObj->getData(Offset, - sizeof(MachOFormat::SymbolTableEntry)); + StringRef Data = getData(Offset, sizeof(MachOFormat::SymbolTableEntry)); return reinterpret_cast(Data.data()); } @@ -148,8 +154,7 @@ MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI, unsigned Index = DRI.d.b; uint64_t Offset = (SymbolTableOffset + Index * sizeof(macho::Symbol64TableEntry)); - StringRef Data = MachOObj->getData(Offset, - sizeof(MachOFormat::Symbol64TableEntry)); + StringRef Data = getData(Offset, sizeof(MachOFormat::Symbol64TableEntry)); return reinterpret_cast(Data.data()); } @@ -167,12 +172,11 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = reinterpret_cast(Command); - StringRef StringTable = - MachOObj->getData(SymtabLoadCmd->StringTableOffset, - SymtabLoadCmd->StringTableSize); + StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset, + SymtabLoadCmd->StringTableSize); uint32_t StringIndex; - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI, SymtabLoadCmd); StringIndex = Entry->StringIndex; @@ -190,7 +194,7 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, uint64_t &Result) const { - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); Result = Entry->Value; if (Entry->SectionIndex) { @@ -213,7 +217,7 @@ error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, uint64_t &Result) const { - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); Result = Entry->Value; } else { @@ -225,11 +229,11 @@ error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, uint64_t &Result) const { - uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; + uint32_t LoadCommandCount = getHeader().NumLoadCommands; uint64_t BeginOffset; uint64_t EndOffset = 0; uint8_t SectionIndex; - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); BeginOffset = Entry->Value; SectionIndex = Entry->SectionIndex; @@ -297,7 +301,7 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, char &Result) const { uint8_t Type, Flags; - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); Type = Entry->Type; Flags = Entry->Flags; @@ -331,7 +335,7 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, uint32_t &Result) const { uint16_t MachOFlags; uint8_t MachOType; - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); MachOFlags = Entry->Flags; MachOType = Entry->Type; @@ -368,7 +372,7 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, section_iterator &Res) const { uint8_t index; - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(Symb); index = Entry->SectionIndex; } else { @@ -387,7 +391,7 @@ error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const { uint8_t n_type; - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(Symb); n_type = Entry->Type; } else { @@ -427,7 +431,7 @@ symbol_iterator MachOObjectFile::begin_symbols() const { symbol_iterator MachOObjectFile::end_symbols() const { DataRefImpl DRI; - DRI.d.a = MachOObj->getHeader().NumLoadCommands; + DRI.d.a = getHeader().NumLoadCommands; return symbol_iterator(SymbolRef(DRI, this)); } @@ -459,7 +463,7 @@ StringRef MachOObjectFile::getLoadName() const { /*===-- Sections ----------------------------------------------------------===*/ void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { - uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; + uint32_t LoadCommandCount = getHeader().NumLoadCommands; while (DRI.d.a < LoadCommandCount) { const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); if (Command->Type == macho::LCT_Segment) { @@ -592,10 +596,10 @@ error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, StringRef &Result) const { if (is64BitLoadCommand(this, DRI)) { const MachOFormat::Section64 *Sect = getSection64(DRI); - Result = MachOObj->getData(Sect->Offset, Sect->Size); + Result = getData(Sect->Offset, Sect->Size); } else { const MachOFormat::Section *Sect = getSection(DRI); - Result = MachOObj->getData(Sect->Offset, Sect->Size); + Result = getData(Sect->Offset, Sect->Size); } return object_error::success; } @@ -654,7 +658,7 @@ error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI, bool &Result) const { - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(DRI); unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; Result = (SectionType == MachO::SectionTypeZeroFill || @@ -695,7 +699,7 @@ error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, getSectionSize(Sec, SectEnd); SectEnd += SectBegin; - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(Symb); uint64_t SymAddr= Entry->Value; Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); @@ -736,7 +740,7 @@ section_iterator MachOObjectFile::begin_sections() const { section_iterator MachOObjectFile::end_sections() const { DataRefImpl DRI; - DRI.d.a = MachOObj->getHeader().NumLoadCommands; + DRI.d.a = getHeader().NumLoadCommands; return section_iterator(SectionRef(DRI, this)); } @@ -745,7 +749,7 @@ section_iterator MachOObjectFile::end_sections() const { const MachOFormat::RelocationEntry * MachOObjectFile::getRelocation(DataRefImpl Rel) const { uint32_t relOffset; - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); relOffset = Sect->RelocationTableOffset; } else { @@ -753,8 +757,7 @@ MachOObjectFile::getRelocation(DataRefImpl Rel) const { relOffset = Sect->RelocationTableOffset; } uint64_t Offset = relOffset + Rel.d.a * sizeof(MachOFormat::RelocationEntry); - StringRef Data = - MachOObj->getData(Offset, sizeof(MachOFormat::RelocationEntry)); + StringRef Data = getData(Offset, sizeof(MachOFormat::RelocationEntry)); return reinterpret_cast(Data.data()); } @@ -767,7 +770,7 @@ error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { const uint8_t* sectAddress = 0; - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); sectAddress += Sect->Address; } else { @@ -813,7 +816,7 @@ error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, for (unsigned i = 0; i < SymbolIdx; i++) { Sym.d.b++; moveToNextSymbol(Sym); - assert(Sym.d.a < MachOObj->getHeader().NumLoadCommands && + assert(Sym.d.a < getHeader().NumLoadCommands && "Relocation symbol index out of range!"); } } @@ -934,7 +937,7 @@ error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, Res = 0; if (!isExtern) { const uint8_t* sectAddress = base(); - if (MachOObj->is64Bit()) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); sectAddress += Sect->Offset; } else { @@ -1292,12 +1295,12 @@ error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData, /*===-- Miscellaneous -----------------------------------------------------===*/ uint8_t MachOObjectFile::getBytesInAddress() const { - return MachOObj->is64Bit() ? 8 : 4; + return is64Bit() ? 8 : 4; } StringRef MachOObjectFile::getFileFormatName() const { - if (!MachOObj->is64Bit()) { - switch (MachOObj->getHeader().CPUType) { + if (!is64Bit()) { + switch (getHeader().CPUType) { case llvm::MachO::CPUTypeI386: return "Mach-O 32-bit i386"; case llvm::MachO::CPUTypeARM: @@ -1305,18 +1308,18 @@ StringRef MachOObjectFile::getFileFormatName() const { case llvm::MachO::CPUTypePowerPC: return "Mach-O 32-bit ppc"; default: - assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 0 && + assert((getHeader().CPUType & llvm::MachO::CPUArchABI64) == 0 && "64-bit object file when we're not 64-bit?"); return "Mach-O 32-bit unknown"; } } // Make sure the cpu type has the correct mask. - assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) + assert((getHeader().CPUType & llvm::MachO::CPUArchABI64) == llvm::MachO::CPUArchABI64 && "32-bit object file when we're 64-bit?"); - switch (MachOObj->getHeader().CPUType) { + switch (getHeader().CPUType) { case llvm::MachO::CPUTypeX86_64: return "Mach-O 64-bit x86-64"; case llvm::MachO::CPUTypePowerPC64: @@ -1327,7 +1330,7 @@ StringRef MachOObjectFile::getFileFormatName() const { } unsigned MachOObjectFile::getArch() const { - switch (MachOObj->getHeader().CPUType) { + switch (getHeader().CPUType) { case llvm::MachO::CPUTypeI386: return Triple::x86; case llvm::MachO::CPUTypeX86_64: -- cgit v1.2.3 From 433611bdf395d08093e3edd52846c1774b46caf2 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 19:26:57 +0000 Subject: Implement MachOObjectFile::getHeader directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178994 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index f011da1e3a..31e8be0f94 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -46,7 +46,7 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, error_code &ec) DataRefImpl DRI; moveToNextSection(DRI); - uint32_t LoadCommandCount = getHeader().NumLoadCommands; + uint32_t LoadCommandCount = getHeader()->NumLoadCommands; while (DRI.d.a < LoadCommandCount) { Sections.push_back(DRI); DRI.d.b++; @@ -80,8 +80,9 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index, return MachOObj->ReadULEB128s(Index, Out); } -const macho::Header &MachOObjectFile::getHeader() const { - return MachOObj->getHeader(); +const MachOFormat::Header *MachOObjectFile::getHeader() const { + StringRef Data = getData(0, sizeof(MachOFormat::Header)); + return reinterpret_cast(Data.data()); } unsigned MachOObjectFile::getHeaderSize() const { @@ -103,7 +104,7 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { /*===-- Symbols -----------------------------------------------------------===*/ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { - uint32_t LoadCommandCount = getHeader().NumLoadCommands; + uint32_t LoadCommandCount = getHeader()->NumLoadCommands; while (DRI.d.a < LoadCommandCount) { const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); if (Command->Type == macho::LCT_Symtab) { @@ -229,7 +230,7 @@ error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, uint64_t &Result) const { - uint32_t LoadCommandCount = getHeader().NumLoadCommands; + uint32_t LoadCommandCount = getHeader()->NumLoadCommands; uint64_t BeginOffset; uint64_t EndOffset = 0; uint8_t SectionIndex; @@ -431,7 +432,7 @@ symbol_iterator MachOObjectFile::begin_symbols() const { symbol_iterator MachOObjectFile::end_symbols() const { DataRefImpl DRI; - DRI.d.a = getHeader().NumLoadCommands; + DRI.d.a = getHeader()->NumLoadCommands; return symbol_iterator(SymbolRef(DRI, this)); } @@ -463,7 +464,7 @@ StringRef MachOObjectFile::getLoadName() const { /*===-- Sections ----------------------------------------------------------===*/ void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { - uint32_t LoadCommandCount = getHeader().NumLoadCommands; + uint32_t LoadCommandCount = getHeader()->NumLoadCommands; while (DRI.d.a < LoadCommandCount) { const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); if (Command->Type == macho::LCT_Segment) { @@ -740,7 +741,7 @@ section_iterator MachOObjectFile::begin_sections() const { section_iterator MachOObjectFile::end_sections() const { DataRefImpl DRI; - DRI.d.a = getHeader().NumLoadCommands; + DRI.d.a = getHeader()->NumLoadCommands; return section_iterator(SectionRef(DRI, this)); } @@ -816,7 +817,7 @@ error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, for (unsigned i = 0; i < SymbolIdx; i++) { Sym.d.b++; moveToNextSymbol(Sym); - assert(Sym.d.a < getHeader().NumLoadCommands && + assert(Sym.d.a < getHeader()->NumLoadCommands && "Relocation symbol index out of range!"); } } @@ -1300,7 +1301,7 @@ uint8_t MachOObjectFile::getBytesInAddress() const { StringRef MachOObjectFile::getFileFormatName() const { if (!is64Bit()) { - switch (getHeader().CPUType) { + switch (getHeader()->CPUType) { case llvm::MachO::CPUTypeI386: return "Mach-O 32-bit i386"; case llvm::MachO::CPUTypeARM: @@ -1308,18 +1309,18 @@ StringRef MachOObjectFile::getFileFormatName() const { case llvm::MachO::CPUTypePowerPC: return "Mach-O 32-bit ppc"; default: - assert((getHeader().CPUType & llvm::MachO::CPUArchABI64) == 0 && + assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64) == 0 && "64-bit object file when we're not 64-bit?"); return "Mach-O 32-bit unknown"; } } // Make sure the cpu type has the correct mask. - assert((getHeader().CPUType & llvm::MachO::CPUArchABI64) + assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64) == llvm::MachO::CPUArchABI64 && "32-bit object file when we're 64-bit?"); - switch (getHeader().CPUType) { + switch (getHeader()->CPUType) { case llvm::MachO::CPUTypeX86_64: return "Mach-O 64-bit x86-64"; case llvm::MachO::CPUTypePowerPC64: @@ -1330,7 +1331,7 @@ StringRef MachOObjectFile::getFileFormatName() const { } unsigned MachOObjectFile::getArch() const { - switch (getHeader().CPUType) { + switch (getHeader()->CPUType) { case llvm::MachO::CPUTypeI386: return Triple::x86; case llvm::MachO::CPUTypeX86_64: -- cgit v1.2.3 From c90cc18b6a28bfd49e74ce609e161ef178f5a2d3 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 19:31:49 +0000 Subject: Implement MachOObjectFile::getHeaderSize directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178995 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 31e8be0f94..ee42bc8f0b 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -86,7 +86,7 @@ const MachOFormat::Header *MachOObjectFile::getHeader() const { } unsigned MachOObjectFile::getHeaderSize() const { - return MachOObj->getHeaderSize(); + return is64Bit() ? macho::Header64Size : macho::Header32Size; } StringRef MachOObjectFile::getData(size_t Offset, size_t Size) const { -- cgit v1.2.3 From 49698a1e691185a2a94d13edcce5c4a8d0db4762 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 19:38:15 +0000 Subject: Implement MachOObjectFile::is64Bit directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178996 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index ee42bc8f0b..7bb8c19525 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -55,7 +55,8 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, error_code &ec) } bool MachOObjectFile::is64Bit() const { - return MachOObj->is64Bit(); + StringRef Magic = getData(0, 4); + return (Magic == "\xFE\xED\xFA\xCF") || (Magic == "\xCF\xFA\xED\xFE"); } const MachOFormat::LoadCommand * -- cgit v1.2.3 From f1cc8001fd405c3ec903cb6caf97a943bb3898ae Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 19:42:15 +0000 Subject: Implement MachOObjectFile::getData directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178997 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 7bb8c19525..75735418cb 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -91,7 +91,7 @@ unsigned MachOObjectFile::getHeaderSize() const { } StringRef MachOObjectFile::getData(size_t Offset, size_t Size) const { - return MachOObj->getData(Offset, Size); + return ObjectFile::getData().substr(Offset, Size); } ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { -- cgit v1.2.3 From 8764c8979c66966b5af62a0a316acead47c038cd Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 20:01:29 +0000 Subject: Make MachOObjectFile independent from MachOObject. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178998 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 75735418cb..4fe791c826 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -15,6 +15,7 @@ #include "llvm/Object/MachO.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/MachOFormat.h" +#include "llvm/Support/DataExtractor.h" #include "llvm/Support/Format.h" #include "llvm/Support/MemoryBuffer.h" #include @@ -29,21 +30,6 @@ namespace object { MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, error_code &ec) : ObjectFile(Binary::ID_MachO, Object) { - // MachOObject takes ownership of the Buffer we passed to it, and - // MachOObjectFile does, too, so we need to make sure they don't get the - // same object. A MemoryBuffer is cheap (it's just a reference to memory, - // not a copy of the memory itself), so just make a new copy here for - // the MachOObjectFile. - MemoryBuffer *NewBuffer = - MemoryBuffer::getMemBuffer(Object->getBuffer(), - Object->getBufferIdentifier(), false); - std::string ErrorStr; - MachOObj.reset(MachOObject::LoadFromBuffer(NewBuffer, &ErrorStr)); - if (!MachOObj) { - ec = object_error::parse_failed; - return; - } - DataRefImpl DRI; moveToNextSection(DRI); uint32_t LoadCommandCount = getHeader()->NumLoadCommands; @@ -78,7 +64,14 @@ MachOObjectFile::getLoadCommandInfo(unsigned Index) const { void MachOObjectFile::ReadULEB128s(uint64_t Index, SmallVectorImpl &Out) const { - return MachOObj->ReadULEB128s(Index, Out); + DataExtractor extractor(ObjectFile::getData(), true, 0); + + uint32_t offset = Index; + uint64_t data = 0; + while (uint64_t delta = extractor.getULEB128(&offset)) { + data += delta; + Out.push_back(data); + } } const MachOFormat::Header *MachOObjectFile::getHeader() const { -- cgit v1.2.3 From 9d55c099d628d7835dd1b502cb29c96cae350099 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 8 Apr 2013 13:25:33 +0000 Subject: Add all 4 MachO object types. Use the stored type to implement is64Bits(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179021 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 4fe791c826..24c916c323 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -28,8 +28,9 @@ using namespace object; namespace llvm { namespace object { -MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, error_code &ec) - : ObjectFile(Binary::ID_MachO, Object) { +MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool Is64bits, + error_code &ec) + : ObjectFile(getMachOType(true, Is64bits), Object) { DataRefImpl DRI; moveToNextSection(DRI); uint32_t LoadCommandCount = getHeader()->NumLoadCommands; @@ -41,8 +42,8 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, error_code &ec) } bool MachOObjectFile::is64Bit() const { - StringRef Magic = getData(0, 4); - return (Magic == "\xFE\xED\xFA\xCF") || (Magic == "\xCF\xFA\xED\xFE"); + unsigned int Type = getType(); + return Type == ID_MachO64L || Type == ID_MachO64B; } const MachOFormat::LoadCommand * @@ -88,8 +89,10 @@ StringRef MachOObjectFile::getData(size_t Offset, size_t Size) const { } ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { + StringRef Magic = Buffer->getBuffer().slice(0, 4); error_code ec; - ObjectFile *Ret = new MachOObjectFile(Buffer, ec); + bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE"; + ObjectFile *Ret = new MachOObjectFile(Buffer, Is64Bits, ec); if (ec) return NULL; return Ret; -- cgit v1.2.3 From a9408bafcc4ea0a42f9dd7a251845372d64abb8b Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 8 Apr 2013 20:18:53 +0000 Subject: Remove is64BitLoadCommand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179048 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 24c916c323..86499cf074 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -489,18 +489,8 @@ error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, return object_error::success; } -static bool is64BitLoadCommand(const MachOObjectFile *MachOObj, - DataRefImpl DRI) { - const MachOFormat::LoadCommand *Command = - MachOObj->getLoadCommandInfo(DRI.d.a); - if (Command->Type == macho::LCT_Segment64) - return true; - assert(Command->Type == macho::LCT_Segment && "Unexpected Type."); - return false; -} - const MachOFormat::Section *MachOObjectFile::getSection(DataRefImpl DRI) const { - assert(!is64BitLoadCommand(this, DRI)); + assert(!is64Bit()); const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); uintptr_t CommandAddr = reinterpret_cast(Command); uintptr_t SectionAddr = CommandAddr + sizeof(macho::SegmentLoadCommand) + @@ -517,7 +507,7 @@ std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { const MachOFormat::Section64 * MachOObjectFile::getSection64(DataRefImpl DRI) const { - assert(is64BitLoadCommand(this, DRI)); + assert(is64Bit()); const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); uintptr_t CommandAddr = reinterpret_cast(Command); uintptr_t SectionAddr = CommandAddr + sizeof(macho::Segment64LoadCommand) + @@ -534,7 +524,7 @@ static StringRef parseSegmentOrSectionName(const char *P) { } ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl DRI) const { - if (is64BitLoadCommand(this, DRI)) { + if (is64Bit()) { const MachOFormat::Section64 *sec = getSection64(DRI); return ArrayRef(sec->Name); } else { @@ -552,7 +542,7 @@ error_code MachOObjectFile::getSectionName(DataRefImpl DRI, ArrayRef MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { - if (is64BitLoadCommand(this, Sec)) { + if (is64Bit()) { const MachOFormat::Section64 *sec = getSection64(Sec); return ArrayRef(sec->SegmentName, 16); } else { @@ -568,7 +558,7 @@ StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const { error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, uint64_t &Result) const { - if (is64BitLoadCommand(this, DRI)) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = Sect->Address; } else { @@ -580,7 +570,7 @@ error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, uint64_t &Result) const { - if (is64BitLoadCommand(this, DRI)) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = Sect->Size; } else { @@ -592,7 +582,7 @@ error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, StringRef &Result) const { - if (is64BitLoadCommand(this, DRI)) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = getData(Sect->Offset, Sect->Size); } else { @@ -604,7 +594,7 @@ error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, uint64_t &Result) const { - if (is64BitLoadCommand(this, DRI)) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = uint64_t(1) << Sect->Align; } else { @@ -616,7 +606,7 @@ error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, error_code MachOObjectFile::isSectionText(DataRefImpl DRI, bool &Result) const { - if (is64BitLoadCommand(this, DRI)) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(DRI); Result = Sect->Flags & macho::SF_PureInstructions; } else { @@ -717,7 +707,7 @@ relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { } relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { uint32_t last_reloc; - if (is64BitLoadCommand(this, Sec)) { + if (is64Bit()) { const MachOFormat::Section64 *Sect = getSection64(Sec); last_reloc = Sect->NumRelocationTableEntries; } else { -- cgit v1.2.3 From 335f1d46d82a4d6b5a7317ccc73178a47b62fc25 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 8 Apr 2013 20:45:01 +0000 Subject: Template the MachO types over the word size. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179051 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 151 +++++++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 65 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 86499cf074..30ab00f450 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -116,7 +116,7 @@ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { } } -const MachOFormat::SymbolTableEntry * +const MachOFormat::SymbolTableEntry * MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = @@ -125,18 +125,20 @@ MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { return getSymbolTableEntry(DRI, SymtabLoadCmd); } -const MachOFormat::SymbolTableEntry * +const MachOFormat::SymbolTableEntry * MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const { uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; unsigned Index = DRI.d.b; uint64_t Offset = (SymbolTableOffset + - Index * sizeof(macho::SymbolTableEntry)); - StringRef Data = getData(Offset, sizeof(MachOFormat::SymbolTableEntry)); - return reinterpret_cast(Data.data()); + Index * sizeof(MachOFormat::SymbolTableEntry)); + StringRef Data = + getData(Offset, sizeof(MachOFormat::SymbolTableEntry)); + return + reinterpret_cast*>(Data.data()); } -const MachOFormat::Symbol64TableEntry* +const MachOFormat::SymbolTableEntry* MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = @@ -145,15 +147,16 @@ MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { return getSymbol64TableEntry(DRI, SymtabLoadCmd); } -const MachOFormat::Symbol64TableEntry* +const MachOFormat::SymbolTableEntry* MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI, const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const { uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; unsigned Index = DRI.d.b; uint64_t Offset = (SymbolTableOffset + - Index * sizeof(macho::Symbol64TableEntry)); - StringRef Data = getData(Offset, sizeof(MachOFormat::Symbol64TableEntry)); - return reinterpret_cast(Data.data()); + Index * sizeof(MachOFormat::SymbolTableEntry)); + StringRef Data = getData(Offset, sizeof(MachOFormat::SymbolTableEntry)); + return + reinterpret_cast*>(Data.data()); } error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, @@ -175,11 +178,11 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, uint32_t StringIndex; if (is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = + const MachOFormat::SymbolTableEntry *Entry = getSymbol64TableEntry(DRI, SymtabLoadCmd); StringIndex = Entry->StringIndex; } else { - const MachOFormat::SymbolTableEntry *Entry = + const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI, SymtabLoadCmd); StringIndex = Entry->StringIndex; } @@ -193,18 +196,20 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, uint64_t &Result) const { if (is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbol64TableEntry(DRI); Result = Entry->Value; if (Entry->SectionIndex) { - const MachOFormat::Section64 *Section = + const MachOFormat::Section *Section = getSection64(Sections[Entry->SectionIndex-1]); Result += Section->Offset - Section->Address; } } else { - const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbolTableEntry(DRI); Result = Entry->Value; if (Entry->SectionIndex) { - const MachOFormat::Section *Section = + const MachOFormat::Section *Section = getSection(Sections[Entry->SectionIndex-1]); Result += Section->Offset - Section->Address; } @@ -216,10 +221,12 @@ error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, uint64_t &Result) const { if (is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbol64TableEntry(DRI); Result = Entry->Value; } else { - const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbolTableEntry(DRI); Result = Entry->Value; } return object_error::success; @@ -232,7 +239,8 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, uint64_t EndOffset = 0; uint8_t SectionIndex; if (is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbol64TableEntry(DRI); BeginOffset = Entry->Value; SectionIndex = Entry->SectionIndex; if (!SectionIndex) { @@ -259,7 +267,8 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, DRI.d.b++; } } else { - const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbolTableEntry(DRI); BeginOffset = Entry->Value; SectionIndex = Entry->SectionIndex; if (!SectionIndex) { @@ -300,11 +309,13 @@ error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, char &Result) const { uint8_t Type, Flags; if (is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbol64TableEntry(DRI); Type = Entry->Type; Flags = Entry->Flags; } else { - const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbolTableEntry(DRI); Type = Entry->Type; Flags = Entry->Flags; } @@ -334,11 +345,13 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, uint16_t MachOFlags; uint8_t MachOType; if (is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbol64TableEntry(DRI); MachOFlags = Entry->Flags; MachOType = Entry->Type; } else { - const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + getSymbolTableEntry(DRI); MachOFlags = Entry->Flags; MachOType = Entry->Type; } @@ -371,10 +384,12 @@ error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, section_iterator &Res) const { uint8_t index; if (is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(Symb); + const MachOFormat::SymbolTableEntry *Entry = + getSymbol64TableEntry(Symb); index = Entry->SectionIndex; } else { - const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(Symb); + const MachOFormat::SymbolTableEntry *Entry = + getSymbolTableEntry(Symb); index = Entry->SectionIndex; } @@ -390,10 +405,12 @@ error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const { uint8_t n_type; if (is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(Symb); + const MachOFormat::SymbolTableEntry *Entry = + getSymbol64TableEntry(Symb); n_type = Entry->Type; } else { - const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(Symb); + const MachOFormat::SymbolTableEntry *Entry = + getSymbolTableEntry(Symb); n_type = Entry->Type; } Res = SymbolRef::ST_Other; @@ -465,14 +482,14 @@ void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { while (DRI.d.a < LoadCommandCount) { const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); if (Command->Type == macho::LCT_Segment) { - const MachOFormat::SegmentLoadCommand *SegmentLoadCmd = - reinterpret_cast(Command); + const MachOFormat::SegmentLoadCommand *SegmentLoadCmd = + reinterpret_cast*>(Command); if (DRI.d.b < SegmentLoadCmd->NumSections) return; } else if (Command->Type == macho::LCT_Segment64) { - const MachOFormat::Segment64LoadCommand *Segment64LoadCmd = - reinterpret_cast(Command); - if (DRI.d.b < Segment64LoadCmd->NumSections) + const MachOFormat::SegmentLoadCommand *SegmentLoadCmd = + reinterpret_cast*>(Command); + if (DRI.d.b < SegmentLoadCmd->NumSections) return; } @@ -489,13 +506,14 @@ error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, return object_error::success; } -const MachOFormat::Section *MachOObjectFile::getSection(DataRefImpl DRI) const { +const MachOFormat::Section * +MachOObjectFile::getSection(DataRefImpl DRI) const { assert(!is64Bit()); const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); uintptr_t CommandAddr = reinterpret_cast(Command); uintptr_t SectionAddr = CommandAddr + sizeof(macho::SegmentLoadCommand) + - DRI.d.b * sizeof(MachOFormat::Section); - return reinterpret_cast(SectionAddr); + DRI.d.b * sizeof(MachOFormat::Section); + return reinterpret_cast*>(SectionAddr); } std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { @@ -505,14 +523,14 @@ std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { return std::distance(Sections.begin(), loc); } -const MachOFormat::Section64 * +const MachOFormat::Section * MachOObjectFile::getSection64(DataRefImpl DRI) const { assert(is64Bit()); const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); uintptr_t CommandAddr = reinterpret_cast(Command); uintptr_t SectionAddr = CommandAddr + sizeof(macho::Segment64LoadCommand) + - DRI.d.b * sizeof(MachOFormat::Section64); - return reinterpret_cast(SectionAddr); + DRI.d.b * sizeof(MachOFormat::Section); + return reinterpret_cast*>(SectionAddr); } static StringRef parseSegmentOrSectionName(const char *P) { @@ -525,10 +543,10 @@ static StringRef parseSegmentOrSectionName(const char *P) { ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl DRI) const { if (is64Bit()) { - const MachOFormat::Section64 *sec = getSection64(DRI); + const MachOFormat::Section *sec = getSection64(DRI); return ArrayRef(sec->Name); } else { - const MachOFormat::Section *sec = getSection(DRI); + const MachOFormat::Section *sec = getSection(DRI); return ArrayRef(sec->Name); } } @@ -543,10 +561,10 @@ error_code MachOObjectFile::getSectionName(DataRefImpl DRI, ArrayRef MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { if (is64Bit()) { - const MachOFormat::Section64 *sec = getSection64(Sec); + const MachOFormat::Section *sec = getSection64(Sec); return ArrayRef(sec->SegmentName, 16); } else { - const MachOFormat::Section *sec = getSection(Sec); + const MachOFormat::Section *sec = getSection(Sec); return ArrayRef(sec->SegmentName); } } @@ -559,10 +577,10 @@ StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const { error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, uint64_t &Result) const { if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section *Sect = getSection64(DRI); Result = Sect->Address; } else { - const MachOFormat::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = Sect->Address; } return object_error::success; @@ -571,10 +589,10 @@ error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, uint64_t &Result) const { if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section *Sect = getSection64(DRI); Result = Sect->Size; } else { - const MachOFormat::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = Sect->Size; } return object_error::success; @@ -583,10 +601,10 @@ error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, StringRef &Result) const { if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section *Sect = getSection64(DRI); Result = getData(Sect->Offset, Sect->Size); } else { - const MachOFormat::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = getData(Sect->Offset, Sect->Size); } return object_error::success; @@ -595,10 +613,10 @@ error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, uint64_t &Result) const { if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section *Sect = getSection64(DRI); Result = uint64_t(1) << Sect->Align; } else { - const MachOFormat::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = uint64_t(1) << Sect->Align; } return object_error::success; @@ -607,10 +625,10 @@ error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, error_code MachOObjectFile::isSectionText(DataRefImpl DRI, bool &Result) const { if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section *Sect = getSection64(DRI); Result = Sect->Flags & macho::SF_PureInstructions; } else { - const MachOFormat::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); Result = Sect->Flags & macho::SF_PureInstructions; } return object_error::success; @@ -647,12 +665,12 @@ error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI, bool &Result) const { if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(DRI); + const MachOFormat::Section *Sect = getSection64(DRI); unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; Result = (SectionType == MachO::SectionTypeZeroFill || SectionType == MachO::SectionTypeZeroFillLarge); } else { - const MachOFormat::Section *Sect = getSection(DRI); + const MachOFormat::Section *Sect = getSection(DRI); unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; Result = (SectionType == MachO::SectionTypeZeroFill || SectionType == MachO::SectionTypeZeroFillLarge); @@ -688,11 +706,13 @@ error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, SectEnd += SectBegin; if (is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = getSymbol64TableEntry(Symb); + const MachOFormat::SymbolTableEntry *Entry = + getSymbol64TableEntry(Symb); uint64_t SymAddr= Entry->Value; Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); } else { - const MachOFormat::SymbolTableEntry *Entry = getSymbolTableEntry(Symb); + const MachOFormat::SymbolTableEntry *Entry = + getSymbolTableEntry(Symb); uint64_t SymAddr= Entry->Value; Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); } @@ -705,13 +725,14 @@ relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { ret.d.b = getSectionIndex(Sec); return relocation_iterator(RelocationRef(ret, this)); } + relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { uint32_t last_reloc; if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(Sec); + const MachOFormat::Section *Sect = getSection64(Sec); last_reloc = Sect->NumRelocationTableEntries; } else { - const MachOFormat::Section *Sect = getSection(Sec); + const MachOFormat::Section *Sect = getSection(Sec); last_reloc = Sect->NumRelocationTableEntries; } DataRefImpl ret; @@ -738,10 +759,10 @@ const MachOFormat::RelocationEntry * MachOObjectFile::getRelocation(DataRefImpl Rel) const { uint32_t relOffset; if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); + const MachOFormat::Section *Sect = getSection64(Sections[Rel.d.b]); relOffset = Sect->RelocationTableOffset; } else { - const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); + const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); relOffset = Sect->RelocationTableOffset; } uint64_t Offset = relOffset + Rel.d.a * sizeof(MachOFormat::RelocationEntry); @@ -759,10 +780,10 @@ error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { const uint8_t* sectAddress = 0; if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); + const MachOFormat::Section *Sect = getSection64(Sections[Rel.d.b]); sectAddress += Sect->Address; } else { - const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); + const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); sectAddress += Sect->Address; } const MachOFormat::RelocationEntry *RE = getRelocation(Rel); @@ -926,10 +947,10 @@ error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, if (!isExtern) { const uint8_t* sectAddress = base(); if (is64Bit()) { - const MachOFormat::Section64 *Sect = getSection64(Sections[Rel.d.b]); + const MachOFormat::Section *Sect = getSection64(Sections[Rel.d.b]); sectAddress += Sect->Offset; } else { - const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); + const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); sectAddress += Sect->Offset; } Res = reinterpret_cast(sectAddress); -- cgit v1.2.3 From 3388589fc102b873ee9b73ffdab0f532ee3ceda6 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 8 Apr 2013 23:57:13 +0000 Subject: Add a SectionBase struct. Use it to share code and when we don't need to know if we have a 32 or 64 bit Section. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179072 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 48 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 30ab00f450..3931c53ac8 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -509,11 +509,8 @@ error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, const MachOFormat::Section * MachOObjectFile::getSection(DataRefImpl DRI) const { assert(!is64Bit()); - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - uintptr_t CommandAddr = reinterpret_cast(Command); - uintptr_t SectionAddr = CommandAddr + sizeof(macho::SegmentLoadCommand) + - DRI.d.b * sizeof(MachOFormat::Section); - return reinterpret_cast*>(SectionAddr); + const MachOFormat::SectionBase *Addr = getSectionBase(DRI); + return reinterpret_cast*>(Addr); } std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { @@ -523,14 +520,27 @@ std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { return std::distance(Sections.begin(), loc); } +const MachOFormat::SectionBase* +MachOObjectFile::getSectionBase(DataRefImpl DRI) const { + const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + uintptr_t CommandAddr = reinterpret_cast(Command); + + bool Is64 = is64Bit(); + unsigned SegmentLoadSize = + Is64 ? sizeof(MachOFormat::SegmentLoadCommand) : + sizeof(MachOFormat::SegmentLoadCommand); + unsigned SectionSize = Is64 ? sizeof(MachOFormat::Section) : + sizeof(MachOFormat::Section); + + uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize; + return reinterpret_cast(SectionAddr); +} + const MachOFormat::Section * MachOObjectFile::getSection64(DataRefImpl DRI) const { assert(is64Bit()); - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - uintptr_t CommandAddr = reinterpret_cast(Command); - uintptr_t SectionAddr = CommandAddr + sizeof(macho::Segment64LoadCommand) + - DRI.d.b * sizeof(MachOFormat::Section); - return reinterpret_cast*>(SectionAddr); + const MachOFormat::SectionBase *Addr = getSectionBase(DRI); + return reinterpret_cast*>(Addr); } static StringRef parseSegmentOrSectionName(const char *P) { @@ -542,13 +552,8 @@ static StringRef parseSegmentOrSectionName(const char *P) { } ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl DRI) const { - if (is64Bit()) { - const MachOFormat::Section *sec = getSection64(DRI); - return ArrayRef(sec->Name); - } else { - const MachOFormat::Section *sec = getSection(DRI); - return ArrayRef(sec->Name); - } + const MachOFormat::SectionBase *Base = getSectionBase(DRI); + return ArrayRef(Base->Name); } error_code MachOObjectFile::getSectionName(DataRefImpl DRI, @@ -560,13 +565,8 @@ error_code MachOObjectFile::getSectionName(DataRefImpl DRI, ArrayRef MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { - if (is64Bit()) { - const MachOFormat::Section *sec = getSection64(Sec); - return ArrayRef(sec->SegmentName, 16); - } else { - const MachOFormat::Section *sec = getSection(Sec); - return ArrayRef(sec->SegmentName); - } + const MachOFormat::SectionBase *Base = getSectionBase(Sec); + return ArrayRef(Base->SegmentName); } StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const { -- cgit v1.2.3 From 7df9c57651574feccd53aec0aac469dea2b48bc6 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 9 Apr 2013 00:22:58 +0000 Subject: Add a SymbolTableEntryBase. Use it when we don't need to know if we have a 32 or 64 bit SymbolTableEntry. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179074 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 74 +++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 47 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 3931c53ac8..ae30105a93 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -116,47 +116,40 @@ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { } } -const MachOFormat::SymbolTableEntry * -MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { +const MachOFormat::SymbolTableEntryBase * +MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI) const { const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = reinterpret_cast(Command); - - return getSymbolTableEntry(DRI, SymtabLoadCmd); + return getSymbolTableEntryBase(DRI, SymtabLoadCmd); } const MachOFormat::SymbolTableEntry * -MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, +MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { + const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI); + return reinterpret_cast*>(Base); +} + +const MachOFormat::SymbolTableEntryBase * +MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI, const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const { uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; unsigned Index = DRI.d.b; - uint64_t Offset = (SymbolTableOffset + - Index * sizeof(MachOFormat::SymbolTableEntry)); - StringRef Data = - getData(Offset, sizeof(MachOFormat::SymbolTableEntry)); - return - reinterpret_cast*>(Data.data()); -} -const MachOFormat::SymbolTableEntry* -MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast(Command); + unsigned SymbolTableEntrySize = is64Bit() ? + sizeof(MachOFormat::SymbolTableEntry) : + sizeof(MachOFormat::SymbolTableEntry); - return getSymbol64TableEntry(DRI, SymtabLoadCmd); + uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize; + StringRef Data = getData(Offset, SymbolTableEntrySize); + return + reinterpret_cast(Data.data()); } const MachOFormat::SymbolTableEntry* -MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI, - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const { - uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; - unsigned Index = DRI.d.b; - uint64_t Offset = (SymbolTableOffset + - Index * sizeof(MachOFormat::SymbolTableEntry)); - StringRef Data = getData(Offset, sizeof(MachOFormat::SymbolTableEntry)); - return - reinterpret_cast*>(Data.data()); +MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { + const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI); + return reinterpret_cast*>(Base); } error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, @@ -176,16 +169,9 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset, SymtabLoadCmd->StringTableSize); - uint32_t StringIndex; - if (is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - getSymbol64TableEntry(DRI, SymtabLoadCmd); - StringIndex = Entry->StringIndex; - } else { - const MachOFormat::SymbolTableEntry *Entry = - getSymbolTableEntry(DRI, SymtabLoadCmd); - StringIndex = Entry->StringIndex; - } + const MachOFormat::SymbolTableEntryBase *Entry = + getSymbolTableEntryBase(DRI, SymtabLoadCmd); + uint32_t StringIndex = Entry->StringIndex; const char *Start = &StringTable.data()[StringIndex]; Result = StringRef(Start); @@ -403,16 +389,10 @@ error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const { - uint8_t n_type; - if (is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - getSymbol64TableEntry(Symb); - n_type = Entry->Type; - } else { - const MachOFormat::SymbolTableEntry *Entry = - getSymbolTableEntry(Symb); - n_type = Entry->Type; - } + const MachOFormat::SymbolTableEntryBase *Entry = + getSymbolTableEntryBase(Symb); + uint8_t n_type = Entry->Type; + Res = SymbolRef::ST_Other; // If this is a STAB debugging symbol, we can do nothing more. -- cgit v1.2.3 From 8faf7df1447ca6ea4a3ff8f82789923d1839fb54 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 9 Apr 2013 01:04:06 +0000 Subject: More uses for SymbolTableEntryBase. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179076 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 44 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index ae30105a93..e1eec36598 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -293,18 +293,9 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, char &Result) const { - uint8_t Type, Flags; - if (is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - getSymbol64TableEntry(DRI); - Type = Entry->Type; - Flags = Entry->Flags; - } else { - const MachOFormat::SymbolTableEntry *Entry = - getSymbolTableEntry(DRI); - Type = Entry->Type; - Flags = Entry->Flags; - } + const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); + uint8_t Type = Entry->Type; + uint16_t Flags = Entry->Flags; char Char; switch (Type & macho::STF_TypeMask) { @@ -328,19 +319,9 @@ error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, uint32_t &Result) const { - uint16_t MachOFlags; - uint8_t MachOType; - if (is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - getSymbol64TableEntry(DRI); - MachOFlags = Entry->Flags; - MachOType = Entry->Type; - } else { - const MachOFormat::SymbolTableEntry *Entry = - getSymbolTableEntry(DRI); - MachOFlags = Entry->Flags; - MachOType = Entry->Type; - } + const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); + uint8_t MachOType = Entry->Type; + uint16_t MachOFlags = Entry->Flags; // TODO: Correctly set SF_ThreadLocal Result = SymbolRef::SF_None; @@ -368,16 +349,9 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, section_iterator &Res) const { - uint8_t index; - if (is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - getSymbol64TableEntry(Symb); - index = Entry->SectionIndex; - } else { - const MachOFormat::SymbolTableEntry *Entry = - getSymbolTableEntry(Symb); - index = Entry->SectionIndex; - } + const MachOFormat::SymbolTableEntryBase *Entry = + getSymbolTableEntryBase(Symb); + uint8_t index = Entry->SectionIndex; if (index == 0) Res = end_sections(); -- cgit v1.2.3 From f6cfc15705140cc958b784a1bc98f7f0f09be6be Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 9 Apr 2013 14:49:08 +0000 Subject: Convert MachOObjectFile to a template. For now it is templated only on being 64 or 32 bits. I will add little/big endian next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179097 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 962 +++++------------------------------------ 1 file changed, 110 insertions(+), 852 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index e1eec36598..20b66d94e8 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -15,6 +15,7 @@ #include "llvm/Object/MachO.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/MachOFormat.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Format.h" #include "llvm/Support/MemoryBuffer.h" @@ -28,34 +29,25 @@ using namespace object; namespace llvm { namespace object { -MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool Is64bits, - error_code &ec) +MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, bool Is64bits, + error_code &ec) : ObjectFile(getMachOType(true, Is64bits), Object) { - DataRefImpl DRI; - moveToNextSection(DRI); - uint32_t LoadCommandCount = getHeader()->NumLoadCommands; - while (DRI.d.a < LoadCommandCount) { - Sections.push_back(DRI); - DRI.d.b++; - moveToNextSection(DRI); - } } -bool MachOObjectFile::is64Bit() const { - unsigned int Type = getType(); - return Type == ID_MachO64L || Type == ID_MachO64B; +bool MachOObjectFileBase::is64Bit() const { + return isa >(this); } -const MachOFormat::LoadCommand * -MachOObjectFile::getLoadCommandInfo(unsigned Index) const { +const MachOObjectFileBase::LoadCommand * +MachOObjectFileBase::getLoadCommandInfo(unsigned Index) const { uint64_t Offset; uint64_t NewOffset = getHeaderSize(); - const MachOFormat::LoadCommand *Load; + const LoadCommand *Load; unsigned I = 0; do { Offset = NewOffset; - StringRef Data = getData(Offset, sizeof(MachOFormat::LoadCommand)); - Load = reinterpret_cast(Data.data()); + StringRef Data = getData(Offset, sizeof(LoadCommand)); + Load = reinterpret_cast(Data.data()); NewOffset = Offset + Load->Size; ++I; } while (I != Index + 1); @@ -63,8 +55,8 @@ MachOObjectFile::getLoadCommandInfo(unsigned Index) const { return Load; } -void MachOObjectFile::ReadULEB128s(uint64_t Index, - SmallVectorImpl &Out) const { +void MachOObjectFileBase::ReadULEB128s(uint64_t Index, + SmallVectorImpl &Out) const { DataExtractor extractor(ObjectFile::getData(), true, 0); uint32_t offset = Index; @@ -75,16 +67,16 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index, } } -const MachOFormat::Header *MachOObjectFile::getHeader() const { - StringRef Data = getData(0, sizeof(MachOFormat::Header)); - return reinterpret_cast(Data.data()); +const MachOObjectFileBase::Header *MachOObjectFileBase::getHeader() const { + StringRef Data = getData(0, sizeof(Header)); + return reinterpret_cast(Data.data()); } -unsigned MachOObjectFile::getHeaderSize() const { +unsigned MachOObjectFileBase::getHeaderSize() const { return is64Bit() ? macho::Header64Size : macho::Header32Size; } -StringRef MachOObjectFile::getData(size_t Offset, size_t Size) const { +StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const { return ObjectFile::getData().substr(Offset, Size); } @@ -92,7 +84,11 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); error_code ec; bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE"; - ObjectFile *Ret = new MachOObjectFile(Buffer, Is64Bits, ec); + ObjectFile *Ret; + if (Is64Bits) + Ret = new MachOObjectFile(Buffer, ec); + else + Ret = new MachOObjectFile(Buffer, ec); if (ec) return NULL; return Ret; @@ -100,13 +96,13 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { /*===-- Symbols -----------------------------------------------------------===*/ -void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { +void MachOObjectFileBase::moveToNextSymbol(DataRefImpl &DRI) const { uint32_t LoadCommandCount = getHeader()->NumLoadCommands; while (DRI.d.a < LoadCommandCount) { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); if (Command->Type == macho::LCT_Symtab) { - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast(Command); + const SymtabLoadCommand *SymtabLoadCmd = + reinterpret_cast(Command); if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries) return; } @@ -116,23 +112,17 @@ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { } } -const MachOFormat::SymbolTableEntryBase * -MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI) const { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast(Command); +const MachOObjectFileBase::SymbolTableEntryBase * +MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI) const { + const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + const SymtabLoadCommand *SymtabLoadCmd = + reinterpret_cast(Command); return getSymbolTableEntryBase(DRI, SymtabLoadCmd); } -const MachOFormat::SymbolTableEntry * -MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { - const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI); - return reinterpret_cast*>(Base); -} - -const MachOFormat::SymbolTableEntryBase * -MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI, - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const { +const MachOObjectFileBase::SymbolTableEntryBase * +MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI, + const SymtabLoadCommand *SymtabLoadCmd) const { uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; unsigned Index = DRI.d.b; @@ -142,34 +132,27 @@ MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI, uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize; StringRef Data = getData(Offset, SymbolTableEntrySize); - return - reinterpret_cast(Data.data()); + return reinterpret_cast(Data.data()); } -const MachOFormat::SymbolTableEntry* -MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { - const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI); - return reinterpret_cast*>(Base); -} - -error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, - SymbolRef &Result) const { +error_code MachOObjectFileBase::getSymbolNext(DataRefImpl DRI, + SymbolRef &Result) const { DRI.d.b++; moveToNextSymbol(DRI); Result = SymbolRef(DRI, this); return object_error::success; } -error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, - StringRef &Result) const { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast(Command); +error_code MachOObjectFileBase::getSymbolName(DataRefImpl DRI, + StringRef &Result) const { + const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + const SymtabLoadCommand *SymtabLoadCmd = + reinterpret_cast(Command); StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset, SymtabLoadCmd->StringTableSize); - const MachOFormat::SymbolTableEntryBase *Entry = + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI, SymtabLoadCmd); uint32_t StringIndex = Entry->StringIndex; @@ -179,121 +162,9 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, return object_error::success; } -error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - getSymbol64TableEntry(DRI); - Result = Entry->Value; - if (Entry->SectionIndex) { - const MachOFormat::Section *Section = - getSection64(Sections[Entry->SectionIndex-1]); - Result += Section->Offset - Section->Address; - } - } else { - const MachOFormat::SymbolTableEntry *Entry = - getSymbolTableEntry(DRI); - Result = Entry->Value; - if (Entry->SectionIndex) { - const MachOFormat::Section *Section = - getSection(Sections[Entry->SectionIndex-1]); - Result += Section->Offset - Section->Address; - } - } - - return object_error::success; -} - -error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - getSymbol64TableEntry(DRI); - Result = Entry->Value; - } else { - const MachOFormat::SymbolTableEntry *Entry = - getSymbolTableEntry(DRI); - Result = Entry->Value; - } - return object_error::success; -} - -error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, - uint64_t &Result) const { - uint32_t LoadCommandCount = getHeader()->NumLoadCommands; - uint64_t BeginOffset; - uint64_t EndOffset = 0; - uint8_t SectionIndex; - if (is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - getSymbol64TableEntry(DRI); - BeginOffset = Entry->Value; - SectionIndex = Entry->SectionIndex; - if (!SectionIndex) { - uint32_t flags = SymbolRef::SF_None; - getSymbolFlags(DRI, flags); - if (flags & SymbolRef::SF_Common) - Result = Entry->Value; - else - Result = UnknownAddressOrSize; - return object_error::success; - } - // Unfortunately symbols are unsorted so we need to touch all - // symbols from load command - DRI.d.b = 0; - uint32_t Command = DRI.d.a; - while (Command == DRI.d.a) { - moveToNextSymbol(DRI); - if (DRI.d.a < LoadCommandCount) { - Entry = getSymbol64TableEntry(DRI); - if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset) - if (!EndOffset || Entry->Value < EndOffset) - EndOffset = Entry->Value; - } - DRI.d.b++; - } - } else { - const MachOFormat::SymbolTableEntry *Entry = - getSymbolTableEntry(DRI); - BeginOffset = Entry->Value; - SectionIndex = Entry->SectionIndex; - if (!SectionIndex) { - uint32_t flags = SymbolRef::SF_None; - getSymbolFlags(DRI, flags); - if (flags & SymbolRef::SF_Common) - Result = Entry->Value; - else - Result = UnknownAddressOrSize; - return object_error::success; - } - // Unfortunately symbols are unsorted so we need to touch all - // symbols from load command - DRI.d.b = 0; - uint32_t Command = DRI.d.a; - while (Command == DRI.d.a) { - moveToNextSymbol(DRI); - if (DRI.d.a < LoadCommandCount) { - Entry = getSymbolTableEntry(DRI); - if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset) - if (!EndOffset || Entry->Value < EndOffset) - EndOffset = Entry->Value; - } - DRI.d.b++; - } - } - if (!EndOffset) { - uint64_t Size; - getSectionSize(Sections[SectionIndex-1], Size); - getSectionAddress(Sections[SectionIndex-1], EndOffset); - EndOffset += Size; - } - Result = EndOffset - BeginOffset; - return object_error::success; -} - -error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, - char &Result) const { - const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); +error_code MachOObjectFileBase::getSymbolNMTypeChar(DataRefImpl DRI, + char &Result) const { + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); uint8_t Type = Entry->Type; uint16_t Flags = Entry->Flags; @@ -317,9 +188,9 @@ error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, return object_error::success; } -error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, - uint32_t &Result) const { - const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); +error_code MachOObjectFileBase::getSymbolFlags(DataRefImpl DRI, + uint32_t &Result) const { + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); uint8_t MachOType = Entry->Type; uint16_t MachOFlags = Entry->Flags; @@ -347,10 +218,9 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, return object_error::success; } -error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const { - const MachOFormat::SymbolTableEntryBase *Entry = - getSymbolTableEntryBase(Symb); +error_code MachOObjectFileBase::getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const { + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb); uint8_t index = Entry->SectionIndex; if (index == 0) @@ -361,10 +231,9 @@ error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, return object_error::success; } -error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const { - const MachOFormat::SymbolTableEntryBase *Entry = - getSymbolTableEntryBase(Symb); +error_code MachOObjectFileBase::getSymbolType(DataRefImpl Symb, + SymbolRef::Type &Res) const { + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb); uint8_t n_type = Entry->Type; Res = SymbolRef::ST_Other; @@ -386,97 +255,61 @@ error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, return object_error::success; } -error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb, - uint64_t &Val) const { - report_fatal_error("getSymbolValue unimplemented in MachOObjectFile"); +error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb, + uint64_t &Val) const { + report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase"); } -symbol_iterator MachOObjectFile::begin_symbols() const { +symbol_iterator MachOObjectFileBase::begin_symbols() const { // DRI.d.a = segment number; DRI.d.b = symbol index. DataRefImpl DRI; moveToNextSymbol(DRI); return symbol_iterator(SymbolRef(DRI, this)); } -symbol_iterator MachOObjectFile::end_symbols() const { +symbol_iterator MachOObjectFileBase::end_symbols() const { DataRefImpl DRI; DRI.d.a = getHeader()->NumLoadCommands; return symbol_iterator(SymbolRef(DRI, this)); } -symbol_iterator MachOObjectFile::begin_dynamic_symbols() const { +symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const { // TODO: implement - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile"); + report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase"); } -symbol_iterator MachOObjectFile::end_dynamic_symbols() const { +symbol_iterator MachOObjectFileBase::end_dynamic_symbols() const { // TODO: implement - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile"); + report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase"); } -library_iterator MachOObjectFile::begin_libraries_needed() const { +library_iterator MachOObjectFileBase::begin_libraries_needed() const { // TODO: implement - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); + report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); } -library_iterator MachOObjectFile::end_libraries_needed() const { +library_iterator MachOObjectFileBase::end_libraries_needed() const { // TODO: implement - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); + report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); } -StringRef MachOObjectFile::getLoadName() const { +StringRef MachOObjectFileBase::getLoadName() const { // TODO: Implement - report_fatal_error("get_load_name() unimplemented in MachOObjectFile"); + report_fatal_error("get_load_name() unimplemented in MachOObjectFileBase"); } /*===-- Sections ----------------------------------------------------------===*/ -void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { - uint32_t LoadCommandCount = getHeader()->NumLoadCommands; - while (DRI.d.a < LoadCommandCount) { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - if (Command->Type == macho::LCT_Segment) { - const MachOFormat::SegmentLoadCommand *SegmentLoadCmd = - reinterpret_cast*>(Command); - if (DRI.d.b < SegmentLoadCmd->NumSections) - return; - } else if (Command->Type == macho::LCT_Segment64) { - const MachOFormat::SegmentLoadCommand *SegmentLoadCmd = - reinterpret_cast*>(Command); - if (DRI.d.b < SegmentLoadCmd->NumSections) - return; - } - - DRI.d.a++; - DRI.d.b = 0; - } -} - -error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, - SectionRef &Result) const { - DRI.d.b++; - moveToNextSection(DRI); - Result = SectionRef(DRI, this); - return object_error::success; -} - -const MachOFormat::Section * -MachOObjectFile::getSection(DataRefImpl DRI) const { - assert(!is64Bit()); - const MachOFormat::SectionBase *Addr = getSectionBase(DRI); - return reinterpret_cast*>(Addr); -} - -std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { +std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const { SectionList::const_iterator loc = std::find(Sections.begin(), Sections.end(), Sec); assert(loc != Sections.end() && "Sec is not a valid section!"); return std::distance(Sections.begin(), loc); } -const MachOFormat::SectionBase* -MachOObjectFile::getSectionBase(DataRefImpl DRI) const { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); +const MachOObjectFileBase::SectionBase* +MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const { + const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); uintptr_t CommandAddr = reinterpret_cast(Command); bool Is64 = is64Bit(); @@ -487,14 +320,7 @@ MachOObjectFile::getSectionBase(DataRefImpl DRI) const { sizeof(MachOFormat::Section); uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize; - return reinterpret_cast(SectionAddr); -} - -const MachOFormat::Section * -MachOObjectFile::getSection64(DataRefImpl DRI) const { - assert(is64Bit()); - const MachOFormat::SectionBase *Addr = getSectionBase(DRI); - return reinterpret_cast*>(Addr); + return reinterpret_cast(SectionAddr); } static StringRef parseSegmentOrSectionName(const char *P) { @@ -505,136 +331,61 @@ static StringRef parseSegmentOrSectionName(const char *P) { return StringRef(P, 16); } -ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl DRI) const { - const MachOFormat::SectionBase *Base = getSectionBase(DRI); +ArrayRef MachOObjectFileBase::getSectionRawName(DataRefImpl DRI) const { + const SectionBase *Base = getSectionBase(DRI); return ArrayRef(Base->Name); } -error_code MachOObjectFile::getSectionName(DataRefImpl DRI, - StringRef &Result) const { +error_code MachOObjectFileBase::getSectionName(DataRefImpl DRI, + StringRef &Result) const { ArrayRef Raw = getSectionRawName(DRI); Result = parseSegmentOrSectionName(Raw.data()); return object_error::success; } ArrayRef -MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { - const MachOFormat::SectionBase *Base = getSectionBase(Sec); +MachOObjectFileBase::getSectionRawFinalSegmentName(DataRefImpl Sec) const { + const SectionBase *Base = getSectionBase(Sec); return ArrayRef(Base->SegmentName); } -StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const { +StringRef +MachOObjectFileBase::getSectionFinalSegmentName(DataRefImpl DRI) const { ArrayRef Raw = getSectionRawFinalSegmentName(DRI); return parseSegmentOrSectionName(Raw.data()); } -error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(DRI); - Result = Sect->Address; - } else { - const MachOFormat::Section *Sect = getSection(DRI); - Result = Sect->Address; - } - return object_error::success; -} - -error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(DRI); - Result = Sect->Size; - } else { - const MachOFormat::Section *Sect = getSection(DRI); - Result = Sect->Size; - } - return object_error::success; -} - -error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, - StringRef &Result) const { - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(DRI); - Result = getData(Sect->Offset, Sect->Size); - } else { - const MachOFormat::Section *Sect = getSection(DRI); - Result = getData(Sect->Offset, Sect->Size); - } - return object_error::success; -} - -error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(DRI); - Result = uint64_t(1) << Sect->Align; - } else { - const MachOFormat::Section *Sect = getSection(DRI); - Result = uint64_t(1) << Sect->Align; - } - return object_error::success; -} - -error_code MachOObjectFile::isSectionText(DataRefImpl DRI, - bool &Result) const { - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(DRI); - Result = Sect->Flags & macho::SF_PureInstructions; - } else { - const MachOFormat::Section *Sect = getSection(DRI); - Result = Sect->Flags & macho::SF_PureInstructions; - } - return object_error::success; -} - -error_code MachOObjectFile::isSectionData(DataRefImpl DRI, - bool &Result) const { +error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI, + bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; } -error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, - bool &Result) const { +error_code MachOObjectFileBase::isSectionBSS(DataRefImpl DRI, + bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; } -error_code MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec, - bool &Result) const { +error_code +MachOObjectFileBase::isSectionRequiredForExecution(DataRefImpl Sec, + bool &Result) const { // FIXME: Unimplemented. Result = true; return object_error::success; } -error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, - bool &Result) const { +error_code MachOObjectFileBase::isSectionVirtual(DataRefImpl Sec, + bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; } -error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI, - bool &Result) const { - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(DRI); - unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; - Result = (SectionType == MachO::SectionTypeZeroFill || - SectionType == MachO::SectionTypeZeroFillLarge); - } else { - const MachOFormat::Section *Sect = getSection(DRI); - unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; - Result = (SectionType == MachO::SectionTypeZeroFill || - SectionType == MachO::SectionTypeZeroFillLarge); - } - - return object_error::success; -} - -error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec, - bool &Result) const { +error_code MachOObjectFileBase::isSectionReadOnlyData(DataRefImpl Sec, + bool &Result) const { // Consider using the code from isSectionText to look for __const sections. // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS // to use section attributes to distinguish code from data. @@ -644,64 +395,13 @@ error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec, return object_error::success; } -error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb, - bool &Result) const { - SymbolRef::Type ST; - getSymbolType(Symb, ST); - if (ST == SymbolRef::ST_Unknown) { - Result = false; - return object_error::success; - } - - uint64_t SectBegin, SectEnd; - getSectionAddress(Sec, SectBegin); - getSectionSize(Sec, SectEnd); - SectEnd += SectBegin; - - if (is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - getSymbol64TableEntry(Symb); - uint64_t SymAddr= Entry->Value; - Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); - } else { - const MachOFormat::SymbolTableEntry *Entry = - getSymbolTableEntry(Symb); - uint64_t SymAddr= Entry->Value; - Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); - } - - return object_error::success; -} - -relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { +relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) const { DataRefImpl ret; ret.d.b = getSectionIndex(Sec); return relocation_iterator(RelocationRef(ret, this)); } -relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { - uint32_t last_reloc; - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(Sec); - last_reloc = Sect->NumRelocationTableEntries; - } else { - const MachOFormat::Section *Sect = getSection(Sec); - last_reloc = Sect->NumRelocationTableEntries; - } - DataRefImpl ret; - ret.d.a = last_reloc; - ret.d.b = getSectionIndex(Sec); - return relocation_iterator(RelocationRef(ret, this)); -} - -section_iterator MachOObjectFile::begin_sections() const { - DataRefImpl DRI; - moveToNextSection(DRI); - return section_iterator(SectionRef(DRI, this)); -} - -section_iterator MachOObjectFile::end_sections() const { +section_iterator MachOObjectFileBase::end_sections() const { DataRefImpl DRI; DRI.d.a = getHeader()->NumLoadCommands; return section_iterator(SectionRef(DRI, this)); @@ -709,208 +409,12 @@ section_iterator MachOObjectFile::end_sections() const { /*===-- Relocations -------------------------------------------------------===*/ -const MachOFormat::RelocationEntry * -MachOObjectFile::getRelocation(DataRefImpl Rel) const { - uint32_t relOffset; - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(Sections[Rel.d.b]); - relOffset = Sect->RelocationTableOffset; - } else { - const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); - relOffset = Sect->RelocationTableOffset; - } - uint64_t Offset = relOffset + Rel.d.a * sizeof(MachOFormat::RelocationEntry); - StringRef Data = getData(Offset, sizeof(MachOFormat::RelocationEntry)); - return reinterpret_cast(Data.data()); -} - -error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, - RelocationRef &Res) const { +error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const { ++Rel.d.a; Res = RelocationRef(Rel, this); return object_error::success; } -error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const { - const uint8_t* sectAddress = 0; - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(Sections[Rel.d.b]); - sectAddress += Sect->Address; - } else { - const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); - sectAddress += Sect->Address; - } - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - uint64_t RelAddr = 0; - if (isScattered) - RelAddr = RE->Word0 & 0xFFFFFF; - else - RelAddr = RE->Word0; - - Res = reinterpret_cast(sectAddress + RelAddr); - return object_error::success; -} -error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, - uint64_t &Res) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - if (isScattered) - Res = RE->Word0 & 0xFFFFFF; - else - Res = RE->Word0; - return object_error::success; -} -error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, - SymbolRef &Res) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - uint32_t SymbolIdx = RE->Word1 & 0xffffff; - bool isExtern = (RE->Word1 >> 27) & 1; - - DataRefImpl Sym; - moveToNextSymbol(Sym); - if (isExtern) { - for (unsigned i = 0; i < SymbolIdx; i++) { - Sym.d.b++; - moveToNextSymbol(Sym); - assert(Sym.d.a < getHeader()->NumLoadCommands && - "Relocation symbol index out of range!"); - } - } - Res = SymbolRef(Sym, this); - return object_error::success; -} -error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, - uint64_t &Res) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - Res = RE->Word0; - Res <<= 32; - Res |= RE->Word1; - return object_error::success; -} -error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl &Result) const { - // TODO: Support scattered relocations. - StringRef res; - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - - unsigned r_type; - if (isScattered) - r_type = (RE->Word0 >> 24) & 0xF; - else - r_type = (RE->Word1 >> 28) & 0xF; - - switch (Arch) { - case Triple::x86: { - static const char *const Table[] = { - "GENERIC_RELOC_VANILLA", - "GENERIC_RELOC_PAIR", - "GENERIC_RELOC_SECTDIFF", - "GENERIC_RELOC_PB_LA_PTR", - "GENERIC_RELOC_LOCAL_SECTDIFF", - "GENERIC_RELOC_TLV" }; - - if (r_type > 6) - res = "Unknown"; - else - res = Table[r_type]; - break; - } - case Triple::x86_64: { - static const char *const Table[] = { - "X86_64_RELOC_UNSIGNED", - "X86_64_RELOC_SIGNED", - "X86_64_RELOC_BRANCH", - "X86_64_RELOC_GOT_LOAD", - "X86_64_RELOC_GOT", - "X86_64_RELOC_SUBTRACTOR", - "X86_64_RELOC_SIGNED_1", - "X86_64_RELOC_SIGNED_2", - "X86_64_RELOC_SIGNED_4", - "X86_64_RELOC_TLV" }; - - if (r_type > 9) - res = "Unknown"; - else - res = Table[r_type]; - break; - } - case Triple::arm: { - static const char *const Table[] = { - "ARM_RELOC_VANILLA", - "ARM_RELOC_PAIR", - "ARM_RELOC_SECTDIFF", - "ARM_RELOC_LOCAL_SECTDIFF", - "ARM_RELOC_PB_LA_PTR", - "ARM_RELOC_BR24", - "ARM_THUMB_RELOC_BR22", - "ARM_THUMB_32BIT_BRANCH", - "ARM_RELOC_HALF", - "ARM_RELOC_HALF_SECTDIFF" }; - - if (r_type > 9) - res = "Unknown"; - else - res = Table[r_type]; - break; - } - case Triple::ppc: { - static const char *const Table[] = { - "PPC_RELOC_VANILLA", - "PPC_RELOC_PAIR", - "PPC_RELOC_BR14", - "PPC_RELOC_BR24", - "PPC_RELOC_HI16", - "PPC_RELOC_LO16", - "PPC_RELOC_HA16", - "PPC_RELOC_LO14", - "PPC_RELOC_SECTDIFF", - "PPC_RELOC_PB_LA_PTR", - "PPC_RELOC_HI16_SECTDIFF", - "PPC_RELOC_LO16_SECTDIFF", - "PPC_RELOC_HA16_SECTDIFF", - "PPC_RELOC_JBSR", - "PPC_RELOC_LO14_SECTDIFF", - "PPC_RELOC_LOCAL_SECTDIFF" }; - - res = Table[r_type]; - break; - } - case Triple::UnknownArch: - res = "Unknown"; - break; - } - Result.append(res.begin(), res.end()); - return object_error::success; -} -error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, - int64_t &Res) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - bool isExtern = (RE->Word1 >> 27) & 1; - Res = 0; - if (!isExtern) { - const uint8_t* sectAddress = base(); - if (is64Bit()) { - const MachOFormat::Section *Sect = getSection64(Sections[Rel.d.b]); - sectAddress += Sect->Offset; - } else { - const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]); - sectAddress += Sect->Offset; - } - Res = reinterpret_cast(sectAddress); - } - return object_error::success; -} // Helper to advance a section or symbol iterator multiple increments at a time. template @@ -928,9 +432,9 @@ void advanceTo(T &it, size_t Val) { report_fatal_error(ec.message()); } -void MachOObjectFile::printRelocationTargetName( - const MachOFormat::RelocationEntry *RE, - raw_string_ostream &fmt) const { +void +MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, + raw_string_ostream &fmt) const { unsigned Arch = getArch(); bool isScattered = (Arch != Triple::x86_64) && (RE->Word0 & macho::RF_Scattered); @@ -998,270 +502,24 @@ void MachOObjectFile::printRelocationTargetName( fmt << S; } -error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - - unsigned Type; - if (isScattered) - Type = (RE->Word0 >> 24) & 0xF; - else - Type = (RE->Word1 >> 28) & 0xF; - - bool isPCRel; - if (isScattered) - isPCRel = ((RE->Word0 >> 30) & 1); - else - isPCRel = ((RE->Word1 >> 24) & 1); - - // Determine any addends that should be displayed with the relocation. - // These require decoding the relocation type, which is triple-specific. - - // X86_64 has entirely custom relocation types. - if (Arch == Triple::x86_64) { - bool isPCRel = ((RE->Word1 >> 24) & 1); - - switch (Type) { - case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD - case macho::RIT_X86_64_GOT: { // X86_64_RELOC_GOT - printRelocationTargetName(RE, fmt); - fmt << "@GOT"; - if (isPCRel) fmt << "PCREL"; - break; - } - case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR - DataRefImpl RelNext = Rel; - RelNext.d.a++; - const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext); - - // X86_64_SUBTRACTOR must be followed by a relocation of type - // X86_64_RELOC_UNSIGNED. - // NOTE: Scattered relocations don't exist on x86_64. - unsigned RType = (RENext->Word1 >> 28) & 0xF; - if (RType != 0) - report_fatal_error("Expected X86_64_RELOC_UNSIGNED after " - "X86_64_RELOC_SUBTRACTOR."); - - // The X86_64_RELOC_UNSIGNED contains the minuend symbol, - // X86_64_SUBTRACTOR contains to the subtrahend. - printRelocationTargetName(RENext, fmt); - fmt << "-"; - printRelocationTargetName(RE, fmt); - break; - } - case macho::RIT_X86_64_TLV: - printRelocationTargetName(RE, fmt); - fmt << "@TLV"; - if (isPCRel) fmt << "P"; - break; - case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1 - printRelocationTargetName(RE, fmt); - fmt << "-1"; - break; - case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2 - printRelocationTargetName(RE, fmt); - fmt << "-2"; - break; - case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4 - printRelocationTargetName(RE, fmt); - fmt << "-4"; - break; - default: - printRelocationTargetName(RE, fmt); - break; - } - // X86 and ARM share some relocation types in common. - } else if (Arch == Triple::x86 || Arch == Triple::arm) { - // Generic relocation types... - switch (Type) { - case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info - return object_error::success; - case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF - DataRefImpl RelNext = Rel; - RelNext.d.a++; - const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext); - - // X86 sect diff's must be followed by a relocation of type - // GENERIC_RELOC_PAIR. - bool isNextScattered = (Arch != Triple::x86_64) && - (RENext->Word0 & macho::RF_Scattered); - unsigned RType; - if (isNextScattered) - RType = (RENext->Word0 >> 24) & 0xF; - else - RType = (RENext->Word1 >> 28) & 0xF; - if (RType != 1) - report_fatal_error("Expected GENERIC_RELOC_PAIR after " - "GENERIC_RELOC_SECTDIFF."); - - printRelocationTargetName(RE, fmt); - fmt << "-"; - printRelocationTargetName(RENext, fmt); - break; - } - } - - if (Arch == Triple::x86) { - // All X86 relocations that need special printing were already - // handled in the generic code. - switch (Type) { - case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF - DataRefImpl RelNext = Rel; - RelNext.d.a++; - const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext); - - // X86 sect diff's must be followed by a relocation of type - // GENERIC_RELOC_PAIR. - bool isNextScattered = (Arch != Triple::x86_64) && - (RENext->Word0 & macho::RF_Scattered); - unsigned RType; - if (isNextScattered) - RType = (RENext->Word0 >> 24) & 0xF; - else - RType = (RENext->Word1 >> 28) & 0xF; - if (RType != 1) - report_fatal_error("Expected GENERIC_RELOC_PAIR after " - "GENERIC_RELOC_LOCAL_SECTDIFF."); - - printRelocationTargetName(RE, fmt); - fmt << "-"; - printRelocationTargetName(RENext, fmt); - break; - } - case macho::RIT_Generic_TLV: { - printRelocationTargetName(RE, fmt); - fmt << "@TLV"; - if (isPCRel) fmt << "P"; - break; - } - default: - printRelocationTargetName(RE, fmt); - } - } else { // ARM-specific relocations - switch (Type) { - case macho::RIT_ARM_Half: // ARM_RELOC_HALF - case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF - // Half relocations steal a bit from the length field to encode - // whether this is an upper16 or a lower16 relocation. - bool isUpper; - if (isScattered) - isUpper = (RE->Word0 >> 28) & 1; - else - isUpper = (RE->Word1 >> 25) & 1; - - if (isUpper) - fmt << ":upper16:("; - else - fmt << ":lower16:("; - printRelocationTargetName(RE, fmt); - - DataRefImpl RelNext = Rel; - RelNext.d.a++; - const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext); - - // ARM half relocs must be followed by a relocation of type - // ARM_RELOC_PAIR. - bool isNextScattered = (Arch != Triple::x86_64) && - (RENext->Word0 & macho::RF_Scattered); - unsigned RType; - if (isNextScattered) - RType = (RENext->Word0 >> 24) & 0xF; - else - RType = (RENext->Word1 >> 28) & 0xF; - - if (RType != 1) - report_fatal_error("Expected ARM_RELOC_PAIR after " - "GENERIC_RELOC_HALF"); - - // NOTE: The half of the target virtual address is stashed in the - // address field of the secondary relocation, but we can't reverse - // engineer the constant offset from it without decoding the movw/movt - // instruction to find the other half in its immediate field. - - // ARM_RELOC_HALF_SECTDIFF encodes the second section in the - // symbol/section pointer of the follow-on relocation. - if (Type == macho::RIT_ARM_HalfDifference) { - fmt << "-"; - printRelocationTargetName(RENext, fmt); - } - - fmt << ")"; - break; - } - default: { - printRelocationTargetName(RE, fmt); - } - } - } - } else - printRelocationTargetName(RE, fmt); - - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - return object_error::success; -} - -error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel, - bool &Result) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - unsigned Type; - if (isScattered) - Type = (RE->Word0 >> 24) & 0xF; - else - Type = (RE->Word1 >> 28) & 0xF; - - Result = false; - - // On arches that use the generic relocations, GENERIC_RELOC_PAIR - // is always hidden. - if (Arch == Triple::x86 || Arch == Triple::arm) { - if (Type == macho::RIT_Pair) Result = true; - } else if (Arch == Triple::x86_64) { - // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows - // an X864_64_RELOC_SUBTRACTOR. - if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) { - DataRefImpl RelPrev = Rel; - RelPrev.d.a--; - const MachOFormat::RelocationEntry *REPrev = getRelocation(RelPrev); - - unsigned PrevType = (REPrev->Word1 >> 28) & 0xF; - - if (PrevType == macho::RIT_X86_64_Subtractor) Result = true; - } - } - - return object_error::success; -} - -error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData, - LibraryRef &Res) const { - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); +error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData, + LibraryRef &Res) const { + report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); } -error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData, - StringRef &Res) const { - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); +error_code MachOObjectFileBase::getLibraryPath(DataRefImpl LibData, + StringRef &Res) const { + report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); } /*===-- Miscellaneous -----------------------------------------------------===*/ -uint8_t MachOObjectFile::getBytesInAddress() const { +uint8_t MachOObjectFileBase::getBytesInAddress() const { return is64Bit() ? 8 : 4; } -StringRef MachOObjectFile::getFileFormatName() const { +StringRef MachOObjectFileBase::getFileFormatName() const { if (!is64Bit()) { switch (getHeader()->CPUType) { case llvm::MachO::CPUTypeI386: @@ -1292,7 +550,7 @@ StringRef MachOObjectFile::getFileFormatName() const { } } -unsigned MachOObjectFile::getArch() const { +unsigned MachOObjectFileBase::getArch() const { switch (getHeader()->CPUType) { case llvm::MachO::CPUTypeI386: return Triple::x86; -- cgit v1.2.3 From a2561a0153237291980722383f409a6499b12efc Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 10 Apr 2013 03:48:25 +0000 Subject: Template the MachO types over endianness. For now they are still only used as little endian. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179147 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 20b66d94e8..33c63b0f89 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -127,8 +127,8 @@ MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI, unsigned Index = DRI.d.b; unsigned SymbolTableEntrySize = is64Bit() ? - sizeof(MachOFormat::SymbolTableEntry) : - sizeof(MachOFormat::SymbolTableEntry); + sizeof(MachOObjectFile::SymbolTableEntry) : + sizeof(MachOObjectFile::SymbolTableEntry); uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize; StringRef Data = getData(Offset, SymbolTableEntrySize); @@ -314,10 +314,10 @@ MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const { bool Is64 = is64Bit(); unsigned SegmentLoadSize = - Is64 ? sizeof(MachOFormat::SegmentLoadCommand) : - sizeof(MachOFormat::SegmentLoadCommand); - unsigned SectionSize = Is64 ? sizeof(MachOFormat::Section) : - sizeof(MachOFormat::Section); + Is64 ? sizeof(MachOObjectFile::SegmentLoadCommand) : + sizeof(MachOObjectFile::SegmentLoadCommand); + unsigned SectionSize = Is64 ? sizeof(MachOObjectFile::Section) : + sizeof(MachOObjectFile::Section); uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize; return reinterpret_cast(SectionAddr); -- cgit v1.2.3 From b08c6df6787971502bd51e30b0f1038c1ea0dc2c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 10 Apr 2013 15:33:44 +0000 Subject: Template MachOObjectFile over endianness too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179179 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 33c63b0f89..f4df8e012c 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -35,7 +35,7 @@ MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, bool Is64bits, } bool MachOObjectFileBase::is64Bit() const { - return isa >(this); + return isa(this); } const MachOObjectFileBase::LoadCommand * @@ -86,9 +86,9 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE"; ObjectFile *Ret; if (Is64Bits) - Ret = new MachOObjectFile(Buffer, ec); + Ret = new MachOObjectFile64Le(Buffer, ec); else - Ret = new MachOObjectFile(Buffer, ec); + Ret = new MachOObjectFile32Le(Buffer, ec); if (ec) return NULL; return Ret; @@ -127,8 +127,8 @@ MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI, unsigned Index = DRI.d.b; unsigned SymbolTableEntrySize = is64Bit() ? - sizeof(MachOObjectFile::SymbolTableEntry) : - sizeof(MachOObjectFile::SymbolTableEntry); + sizeof(MachOObjectFile64Le::SymbolTableEntry) : + sizeof(MachOObjectFile32Le::SymbolTableEntry); uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize; StringRef Data = getData(Offset, SymbolTableEntrySize); @@ -314,10 +314,10 @@ MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const { bool Is64 = is64Bit(); unsigned SegmentLoadSize = - Is64 ? sizeof(MachOObjectFile::SegmentLoadCommand) : - sizeof(MachOObjectFile::SegmentLoadCommand); - unsigned SectionSize = Is64 ? sizeof(MachOObjectFile::Section) : - sizeof(MachOObjectFile::Section); + Is64 ? sizeof(MachOObjectFile64Le::SegmentLoadCommand) : + sizeof(MachOObjectFile32Le::SegmentLoadCommand); + unsigned SectionSize = Is64 ? sizeof(MachOObjectFile64Le::Section) : + sizeof(MachOObjectFile32Le::Section); uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize; return reinterpret_cast(SectionAddr); -- cgit v1.2.3 From 8bf80061ba44af16b4597627ca7d6d7fc1bed64e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 11 Apr 2013 02:21:31 +0000 Subject: Fix MachO's getRelocationAdditionalInfo. It was returning the loaded address of the section containing the relocation, which really doesn't seem to be the intent of this function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179255 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index f4df8e012c..c846206e6e 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -512,6 +512,12 @@ error_code MachOObjectFileBase::getLibraryPath(DataRefImpl LibData, report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); } +error_code MachOObjectFileBase::getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Res) const { + Res = 0; + return object_error::success; +} + /*===-- Miscellaneous -----------------------------------------------------===*/ -- cgit v1.2.3 From 4edf092787cab37d46da96eb1e9df0677ca30b1d Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 11 Apr 2013 16:31:37 +0000 Subject: Print more information about relocations. With this patch llvm-readobj now prints if a relocation is pcrel, its length, if it is extern and if it is scattered. It also refactors the code a bit to use bit fields instead of shifts and masks all over the place. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179294 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 52 +++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 8 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index c846206e6e..98e28db88d 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -80,6 +80,46 @@ StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const { return ObjectFile::getData().substr(Offset, Size); } +const MachOObjectFileBase::RelocationEntry * +MachOObjectFileBase::getRelocation(DataRefImpl Rel) const { + if (const MachOObjectFile32Le *O = dyn_cast(this)) + return O->getRelocation(Rel); + const MachOObjectFile64Le *O = dyn_cast(this); + return O->getRelocation(Rel); +} + +bool MachOObjectFileBase::isScattered(const RelocationEntry *RE) const { + unsigned Arch = getArch(); + return (Arch != Triple::x86_64) && (RE->Address & macho::RF_Scattered); +} + +bool MachOObjectFileBase::isPCRel(const RelocationEntry *RE) const { + if (isScattered(RE)) { + const ScatteredRelocationEntry *SRE = + reinterpret_cast(RE); + return SRE->PCRel; + } + return RE->PCRel; +} + +unsigned MachOObjectFileBase::getLength(const RelocationEntry *RE) const { + if (isScattered(RE)) { + const ScatteredRelocationEntry *SRE = + reinterpret_cast(RE); + return SRE->Length; + } + return RE->Length; +} + +unsigned MachOObjectFileBase::getType(const RelocationEntry *RE) const { + if (isScattered(RE)) { + const ScatteredRelocationEntry *SRE = + reinterpret_cast(RE); + return SRE->Type; + } + return RE->Type; +} + ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); error_code ec; @@ -435,16 +475,12 @@ void advanceTo(T &it, size_t Val) { void MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, raw_string_ostream &fmt) const { - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - // Target of a scattered relocation is an address. In the interest of // generating pretty output, scan through the symbol table looking for a // symbol that aligns with that address. If we find one, print it. // Otherwise, we just print the hex address of the target. - if (isScattered) { - uint32_t Val = RE->Word1; + if (isScattered(RE)) { + uint32_t Val = RE->SymbolNum; error_code ec; for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE; @@ -486,8 +522,8 @@ MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, } StringRef S; - bool isExtern = (RE->Word1 >> 27) & 1; - uint32_t Val = RE->Word1 & 0xFFFFFF; + bool isExtern = RE->External; + uint32_t Val = RE->Address; if (isExtern) { symbol_iterator SI = begin_symbols(); -- cgit v1.2.3 From 59a8b5a8f09ae4c4f3b0e3d8025c6b4cf3ca1f1a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 11 Apr 2013 17:46:10 +0000 Subject: Revert my last two commits while I debug what is wrong in a big endian host. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179303 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 52 +++++++----------------------------------- 1 file changed, 8 insertions(+), 44 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 98e28db88d..c846206e6e 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -80,46 +80,6 @@ StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const { return ObjectFile::getData().substr(Offset, Size); } -const MachOObjectFileBase::RelocationEntry * -MachOObjectFileBase::getRelocation(DataRefImpl Rel) const { - if (const MachOObjectFile32Le *O = dyn_cast(this)) - return O->getRelocation(Rel); - const MachOObjectFile64Le *O = dyn_cast(this); - return O->getRelocation(Rel); -} - -bool MachOObjectFileBase::isScattered(const RelocationEntry *RE) const { - unsigned Arch = getArch(); - return (Arch != Triple::x86_64) && (RE->Address & macho::RF_Scattered); -} - -bool MachOObjectFileBase::isPCRel(const RelocationEntry *RE) const { - if (isScattered(RE)) { - const ScatteredRelocationEntry *SRE = - reinterpret_cast(RE); - return SRE->PCRel; - } - return RE->PCRel; -} - -unsigned MachOObjectFileBase::getLength(const RelocationEntry *RE) const { - if (isScattered(RE)) { - const ScatteredRelocationEntry *SRE = - reinterpret_cast(RE); - return SRE->Length; - } - return RE->Length; -} - -unsigned MachOObjectFileBase::getType(const RelocationEntry *RE) const { - if (isScattered(RE)) { - const ScatteredRelocationEntry *SRE = - reinterpret_cast(RE); - return SRE->Type; - } - return RE->Type; -} - ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); error_code ec; @@ -475,12 +435,16 @@ void advanceTo(T &it, size_t Val) { void MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, raw_string_ostream &fmt) const { + unsigned Arch = getArch(); + bool isScattered = (Arch != Triple::x86_64) && + (RE->Word0 & macho::RF_Scattered); + // Target of a scattered relocation is an address. In the interest of // generating pretty output, scan through the symbol table looking for a // symbol that aligns with that address. If we find one, print it. // Otherwise, we just print the hex address of the target. - if (isScattered(RE)) { - uint32_t Val = RE->SymbolNum; + if (isScattered) { + uint32_t Val = RE->Word1; error_code ec; for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE; @@ -522,8 +486,8 @@ MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, } StringRef S; - bool isExtern = RE->External; - uint32_t Val = RE->Address; + bool isExtern = (RE->Word1 >> 27) & 1; + uint32_t Val = RE->Word1 & 0xFFFFFF; if (isExtern) { symbol_iterator SI = begin_symbols(); -- cgit v1.2.3 From e292347503cd7598429c08f9984ab3e0a44ab8a3 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 12 Apr 2013 00:17:33 +0000 Subject: Add 179294 back, but don't use bit fields so that it works on big endian hosts. Original message: Print more information about relocations. With this patch llvm-readobj now prints if a relocation is pcrel, its length, if it is extern and if it is scattered. It also refactors the code a bit to use bit fields instead of shifts and masks all over the place. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179345 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 52 +++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 8 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index c846206e6e..627e7485a6 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -80,6 +80,46 @@ StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const { return ObjectFile::getData().substr(Offset, Size); } +const MachOObjectFileBase::RelocationEntry * +MachOObjectFileBase::getRelocation(DataRefImpl Rel) const { + if (const MachOObjectFile32Le *O = dyn_cast(this)) + return O->getRelocation(Rel); + const MachOObjectFile64Le *O = dyn_cast(this); + return O->getRelocation(Rel); +} + +bool MachOObjectFileBase::isScattered(const RelocationEntry *RE) const { + unsigned Arch = getArch(); + return (Arch != Triple::x86_64) && (RE->Address & macho::RF_Scattered); +} + +bool MachOObjectFileBase::isPCRel(const RelocationEntry *RE) const { + if (isScattered(RE)) { + const ScatteredRelocationEntry *SRE = + reinterpret_cast(RE); + return SRE->getPCRel(); + } + return RE->getPCRel(); +} + +unsigned MachOObjectFileBase::getLength(const RelocationEntry *RE) const { + if (isScattered(RE)) { + const ScatteredRelocationEntry *SRE = + reinterpret_cast(RE); + return SRE->getLength(); + } + return RE->getLength(); +} + +unsigned MachOObjectFileBase::getType(const RelocationEntry *RE) const { + if (isScattered(RE)) { + const ScatteredRelocationEntry *SRE = + reinterpret_cast(RE); + return SRE->getType(); + } + return RE->getType(); +} + ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); error_code ec; @@ -435,16 +475,12 @@ void advanceTo(T &it, size_t Val) { void MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, raw_string_ostream &fmt) const { - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - // Target of a scattered relocation is an address. In the interest of // generating pretty output, scan through the symbol table looking for a // symbol that aligns with that address. If we find one, print it. // Otherwise, we just print the hex address of the target. - if (isScattered) { - uint32_t Val = RE->Word1; + if (isScattered(RE)) { + uint32_t Val = RE->SymbolNum; error_code ec; for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE; @@ -486,8 +522,8 @@ MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, } StringRef S; - bool isExtern = (RE->Word1 >> 27) & 1; - uint32_t Val = RE->Word1 & 0xFFFFFF; + bool isExtern = RE->getExternal(); + uint32_t Val = RE->Address; if (isExtern) { symbol_iterator SI = begin_symbols(); -- cgit v1.2.3 From da2a2372c6ae715befae7f086afe769dd80814f3 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 13 Apr 2013 01:45:40 +0000 Subject: Finish templating MachObjectFile over endianness. We are now able to handle big endian macho files in llvm-readobject. Thanks to David Fang for providing the object files. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179440 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 432 ++--------------------------------------- 1 file changed, 15 insertions(+), 417 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 627e7485a6..192e7555b4 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -29,30 +29,14 @@ using namespace object; namespace llvm { namespace object { -MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, bool Is64bits, +MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, + bool IsLittleEndian, bool Is64bits, error_code &ec) - : ObjectFile(getMachOType(true, Is64bits), Object) { + : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) { } bool MachOObjectFileBase::is64Bit() const { - return isa(this); -} - -const MachOObjectFileBase::LoadCommand * -MachOObjectFileBase::getLoadCommandInfo(unsigned Index) const { - uint64_t Offset; - uint64_t NewOffset = getHeaderSize(); - const LoadCommand *Load; - unsigned I = 0; - do { - Offset = NewOffset; - StringRef Data = getData(Offset, sizeof(LoadCommand)); - Load = reinterpret_cast(Data.data()); - NewOffset = Offset + Load->Size; - ++I; - } while (I != Index + 1); - - return Load; + return isa(this) || isa(this); } void MachOObjectFileBase::ReadULEB128s(uint64_t Index, @@ -67,11 +51,6 @@ void MachOObjectFileBase::ReadULEB128s(uint64_t Index, } } -const MachOObjectFileBase::Header *MachOObjectFileBase::getHeader() const { - StringRef Data = getData(0, sizeof(Header)); - return reinterpret_cast(Data.data()); -} - unsigned MachOObjectFileBase::getHeaderSize() const { return is64Bit() ? macho::Header64Size : macho::Header32Size; } @@ -80,55 +59,21 @@ StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const { return ObjectFile::getData().substr(Offset, Size); } -const MachOObjectFileBase::RelocationEntry * -MachOObjectFileBase::getRelocation(DataRefImpl Rel) const { - if (const MachOObjectFile32Le *O = dyn_cast(this)) - return O->getRelocation(Rel); - const MachOObjectFile64Le *O = dyn_cast(this); - return O->getRelocation(Rel); -} - -bool MachOObjectFileBase::isScattered(const RelocationEntry *RE) const { - unsigned Arch = getArch(); - return (Arch != Triple::x86_64) && (RE->Address & macho::RF_Scattered); -} - -bool MachOObjectFileBase::isPCRel(const RelocationEntry *RE) const { - if (isScattered(RE)) { - const ScatteredRelocationEntry *SRE = - reinterpret_cast(RE); - return SRE->getPCRel(); - } - return RE->getPCRel(); -} - -unsigned MachOObjectFileBase::getLength(const RelocationEntry *RE) const { - if (isScattered(RE)) { - const ScatteredRelocationEntry *SRE = - reinterpret_cast(RE); - return SRE->getLength(); - } - return RE->getLength(); -} - -unsigned MachOObjectFileBase::getType(const RelocationEntry *RE) const { - if (isScattered(RE)) { - const ScatteredRelocationEntry *SRE = - reinterpret_cast(RE); - return SRE->getType(); - } - return RE->getType(); -} - ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); error_code ec; - bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE"; ObjectFile *Ret; - if (Is64Bits) - Ret = new MachOObjectFile64Le(Buffer, ec); + if (Magic == "\xFE\xED\xFA\xCE") + Ret = new MachOObjectFileBE32(Buffer, ec); + else if (Magic == "\xCE\xFA\xED\xFE") + Ret = new MachOObjectFileLE32(Buffer, ec); + else if (Magic == "\xFE\xED\xFA\xCF") + Ret = new MachOObjectFileBE64(Buffer, ec); + else if (Magic == "\xCF\xFA\xED\xFE") + Ret = new MachOObjectFileLE64(Buffer, ec); else - Ret = new MachOObjectFile32Le(Buffer, ec); + return NULL; + if (ec) return NULL; return Ret; @@ -136,183 +81,11 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { /*===-- Symbols -----------------------------------------------------------===*/ -void MachOObjectFileBase::moveToNextSymbol(DataRefImpl &DRI) const { - uint32_t LoadCommandCount = getHeader()->NumLoadCommands; - while (DRI.d.a < LoadCommandCount) { - const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - if (Command->Type == macho::LCT_Symtab) { - const SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast(Command); - if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries) - return; - } - - DRI.d.a++; - DRI.d.b = 0; - } -} - -const MachOObjectFileBase::SymbolTableEntryBase * -MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI) const { - const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - const SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast(Command); - return getSymbolTableEntryBase(DRI, SymtabLoadCmd); -} - -const MachOObjectFileBase::SymbolTableEntryBase * -MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI, - const SymtabLoadCommand *SymtabLoadCmd) const { - uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; - unsigned Index = DRI.d.b; - - unsigned SymbolTableEntrySize = is64Bit() ? - sizeof(MachOObjectFile64Le::SymbolTableEntry) : - sizeof(MachOObjectFile32Le::SymbolTableEntry); - - uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize; - StringRef Data = getData(Offset, SymbolTableEntrySize); - return reinterpret_cast(Data.data()); -} - -error_code MachOObjectFileBase::getSymbolNext(DataRefImpl DRI, - SymbolRef &Result) const { - DRI.d.b++; - moveToNextSymbol(DRI); - Result = SymbolRef(DRI, this); - return object_error::success; -} - -error_code MachOObjectFileBase::getSymbolName(DataRefImpl DRI, - StringRef &Result) const { - const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - const SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast(Command); - - StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset, - SymtabLoadCmd->StringTableSize); - - const SymbolTableEntryBase *Entry = - getSymbolTableEntryBase(DRI, SymtabLoadCmd); - uint32_t StringIndex = Entry->StringIndex; - - const char *Start = &StringTable.data()[StringIndex]; - Result = StringRef(Start); - - return object_error::success; -} - -error_code MachOObjectFileBase::getSymbolNMTypeChar(DataRefImpl DRI, - char &Result) const { - const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); - uint8_t Type = Entry->Type; - uint16_t Flags = Entry->Flags; - - char Char; - switch (Type & macho::STF_TypeMask) { - case macho::STT_Undefined: - Char = 'u'; - break; - case macho::STT_Absolute: - case macho::STT_Section: - Char = 's'; - break; - default: - Char = '?'; - break; - } - - if (Flags & (macho::STF_External | macho::STF_PrivateExtern)) - Char = toupper(static_cast(Char)); - Result = Char; - return object_error::success; -} - -error_code MachOObjectFileBase::getSymbolFlags(DataRefImpl DRI, - uint32_t &Result) const { - const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); - uint8_t MachOType = Entry->Type; - uint16_t MachOFlags = Entry->Flags; - - // TODO: Correctly set SF_ThreadLocal - Result = SymbolRef::SF_None; - - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined) - Result |= SymbolRef::SF_Undefined; - - if (MachOFlags & macho::STF_StabsEntryMask) - Result |= SymbolRef::SF_FormatSpecific; - - if (MachOType & MachO::NlistMaskExternal) { - Result |= SymbolRef::SF_Global; - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined) - Result |= SymbolRef::SF_Common; - } - - if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef)) - Result |= SymbolRef::SF_Weak; - - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute) - Result |= SymbolRef::SF_Absolute; - - return object_error::success; -} - -error_code MachOObjectFileBase::getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const { - const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb); - uint8_t index = Entry->SectionIndex; - - if (index == 0) - Res = end_sections(); - else - Res = section_iterator(SectionRef(Sections[index-1], this)); - - return object_error::success; -} - -error_code MachOObjectFileBase::getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const { - const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb); - uint8_t n_type = Entry->Type; - - Res = SymbolRef::ST_Other; - - // If this is a STAB debugging symbol, we can do nothing more. - if (n_type & MachO::NlistMaskStab) { - Res = SymbolRef::ST_Debug; - return object_error::success; - } - - switch (n_type & MachO::NlistMaskType) { - case MachO::NListTypeUndefined : - Res = SymbolRef::ST_Unknown; - break; - case MachO::NListTypeSection : - Res = SymbolRef::ST_Function; - break; - } - return object_error::success; -} - error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb, uint64_t &Val) const { report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase"); } -symbol_iterator MachOObjectFileBase::begin_symbols() const { - // DRI.d.a = segment number; DRI.d.b = symbol index. - DataRefImpl DRI; - moveToNextSymbol(DRI); - return symbol_iterator(SymbolRef(DRI, this)); -} - -symbol_iterator MachOObjectFileBase::end_symbols() const { - DataRefImpl DRI; - DRI.d.a = getHeader()->NumLoadCommands; - return symbol_iterator(SymbolRef(DRI, this)); -} - symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const { // TODO: implement report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase"); @@ -347,23 +120,7 @@ std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const { return std::distance(Sections.begin(), loc); } -const MachOObjectFileBase::SectionBase* -MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const { - const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - uintptr_t CommandAddr = reinterpret_cast(Command); - - bool Is64 = is64Bit(); - unsigned SegmentLoadSize = - Is64 ? sizeof(MachOObjectFile64Le::SegmentLoadCommand) : - sizeof(MachOObjectFile32Le::SegmentLoadCommand); - unsigned SectionSize = Is64 ? sizeof(MachOObjectFile64Le::Section) : - sizeof(MachOObjectFile32Le::Section); - - uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize; - return reinterpret_cast(SectionAddr); -} - -static StringRef parseSegmentOrSectionName(const char *P) { +StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const { if (P[15] == 0) // Null terminated. return P; @@ -371,30 +128,6 @@ static StringRef parseSegmentOrSectionName(const char *P) { return StringRef(P, 16); } -ArrayRef MachOObjectFileBase::getSectionRawName(DataRefImpl DRI) const { - const SectionBase *Base = getSectionBase(DRI); - return ArrayRef(Base->Name); -} - -error_code MachOObjectFileBase::getSectionName(DataRefImpl DRI, - StringRef &Result) const { - ArrayRef Raw = getSectionRawName(DRI); - Result = parseSegmentOrSectionName(Raw.data()); - return object_error::success; -} - -ArrayRef -MachOObjectFileBase::getSectionRawFinalSegmentName(DataRefImpl Sec) const { - const SectionBase *Base = getSectionBase(Sec); - return ArrayRef(Base->SegmentName); -} - -StringRef -MachOObjectFileBase::getSectionFinalSegmentName(DataRefImpl DRI) const { - ArrayRef Raw = getSectionRawFinalSegmentName(DRI); - return parseSegmentOrSectionName(Raw.data()); -} - error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI, bool &Result) const { // FIXME: Unimplemented. @@ -441,11 +174,6 @@ relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) con return relocation_iterator(RelocationRef(ret, this)); } -section_iterator MachOObjectFileBase::end_sections() const { - DataRefImpl DRI; - DRI.d.a = getHeader()->NumLoadCommands; - return section_iterator(SectionRef(DRI, this)); -} /*===-- Relocations -------------------------------------------------------===*/ @@ -456,88 +184,6 @@ error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel, return object_error::success; } -// Helper to advance a section or symbol iterator multiple increments at a time. -template -error_code advance(T &it, size_t Val) { - error_code ec; - while (Val--) { - it.increment(ec); - } - return ec; -} - -template -void advanceTo(T &it, size_t Val) { - if (error_code ec = advance(it, Val)) - report_fatal_error(ec.message()); -} - -void -MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, - raw_string_ostream &fmt) const { - // Target of a scattered relocation is an address. In the interest of - // generating pretty output, scan through the symbol table looking for a - // symbol that aligns with that address. If we find one, print it. - // Otherwise, we just print the hex address of the target. - if (isScattered(RE)) { - uint32_t Val = RE->SymbolNum; - - error_code ec; - for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE; - SI.increment(ec)) { - if (ec) report_fatal_error(ec.message()); - - uint64_t Addr; - StringRef Name; - - if ((ec = SI->getAddress(Addr))) - report_fatal_error(ec.message()); - if (Addr != Val) continue; - if ((ec = SI->getName(Name))) - report_fatal_error(ec.message()); - fmt << Name; - return; - } - - // If we couldn't find a symbol that this relocation refers to, try - // to find a section beginning instead. - for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE; - SI.increment(ec)) { - if (ec) report_fatal_error(ec.message()); - - uint64_t Addr; - StringRef Name; - - if ((ec = SI->getAddress(Addr))) - report_fatal_error(ec.message()); - if (Addr != Val) continue; - if ((ec = SI->getName(Name))) - report_fatal_error(ec.message()); - fmt << Name; - return; - } - - fmt << format("0x%x", Val); - return; - } - - StringRef S; - bool isExtern = RE->getExternal(); - uint32_t Val = RE->Address; - - if (isExtern) { - symbol_iterator SI = begin_symbols(); - advanceTo(SI, Val); - SI->getName(S); - } else { - section_iterator SI = begin_sections(); - advanceTo(SI, Val); - SI->getName(S); - } - - fmt << S; -} - error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const { report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); @@ -561,53 +207,5 @@ uint8_t MachOObjectFileBase::getBytesInAddress() const { return is64Bit() ? 8 : 4; } -StringRef MachOObjectFileBase::getFileFormatName() const { - if (!is64Bit()) { - switch (getHeader()->CPUType) { - case llvm::MachO::CPUTypeI386: - return "Mach-O 32-bit i386"; - case llvm::MachO::CPUTypeARM: - return "Mach-O arm"; - case llvm::MachO::CPUTypePowerPC: - return "Mach-O 32-bit ppc"; - default: - assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64) == 0 && - "64-bit object file when we're not 64-bit?"); - return "Mach-O 32-bit unknown"; - } - } - - // Make sure the cpu type has the correct mask. - assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64) - == llvm::MachO::CPUArchABI64 && - "32-bit object file when we're 64-bit?"); - - switch (getHeader()->CPUType) { - case llvm::MachO::CPUTypeX86_64: - return "Mach-O 64-bit x86-64"; - case llvm::MachO::CPUTypePowerPC64: - return "Mach-O 64-bit ppc64"; - default: - return "Mach-O 64-bit unknown"; - } -} - -unsigned MachOObjectFileBase::getArch() const { - switch (getHeader()->CPUType) { - case llvm::MachO::CPUTypeI386: - return Triple::x86; - case llvm::MachO::CPUTypeX86_64: - return Triple::x86_64; - case llvm::MachO::CPUTypeARM: - return Triple::arm; - case llvm::MachO::CPUTypePowerPC: - return Triple::ppc; - case llvm::MachO::CPUTypePowerPC64: - return Triple::ppc64; - default: - return Triple::UnknownArch; - } -} - } // end namespace object } // end namespace llvm -- cgit v1.2.3 From fd7aa38e304a09fa0ef51b85b773b649b7e58c5e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 18 Apr 2013 18:08:55 +0000 Subject: At Jim Grosbach's request detemplate Object/MachO.h. We are still able to handle mixed endian objects by swapping one struct at a time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179778 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 1461 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 1379 insertions(+), 82 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 192e7555b4..f5910dd95d 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -15,9 +15,9 @@ #include "llvm/Object/MachO.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/MachOFormat.h" -#include "llvm/Support/Casting.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Format.h" +#include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" #include #include @@ -29,98 +29,222 @@ using namespace object; namespace llvm { namespace object { -MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, - bool IsLittleEndian, bool Is64bits, - error_code &ec) - : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) { +struct SymbolTableEntryBase { + uint32_t StringIndex; + uint8_t Type; + uint8_t SectionIndex; + uint16_t Flags; +}; + +struct SectionBase { + char Name[16]; + char SegmentName[16]; +}; + +template +static void SwapValue(T &Value) { + Value = sys::SwapByteOrder(Value); } -bool MachOObjectFileBase::is64Bit() const { - return isa(this) || isa(this); +template +static void SwapStruct(T &Value); + +template<> +void SwapStruct(macho::RelocationEntry &H) { + SwapValue(H.Word0); + SwapValue(H.Word1); } -void MachOObjectFileBase::ReadULEB128s(uint64_t Index, - SmallVectorImpl &Out) const { - DataExtractor extractor(ObjectFile::getData(), true, 0); +template<> +void SwapStruct(macho::LoadCommand &L) { + SwapValue(L.Type); + SwapValue(L.Size); +} - uint32_t offset = Index; - uint64_t data = 0; - while (uint64_t delta = extractor.getULEB128(&offset)) { - data += delta; - Out.push_back(data); - } +template<> +void SwapStruct(SymbolTableEntryBase &S) { + SwapValue(S.StringIndex); + SwapValue(S.Flags); } -unsigned MachOObjectFileBase::getHeaderSize() const { - return is64Bit() ? macho::Header64Size : macho::Header32Size; +template<> +void SwapStruct(macho::Section &S) { + SwapValue(S.Address); + SwapValue(S.Size); + SwapValue(S.Offset); + SwapValue(S.Align); + SwapValue(S.RelocationTableOffset); + SwapValue(S.NumRelocationTableEntries); + SwapValue(S.Flags); + SwapValue(S.Reserved1); + SwapValue(S.Reserved2); } -StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const { - return ObjectFile::getData().substr(Offset, Size); +template<> +void SwapStruct(macho::Section64 &S) { + SwapValue(S.Address); + SwapValue(S.Size); + SwapValue(S.Offset); + SwapValue(S.Align); + SwapValue(S.RelocationTableOffset); + SwapValue(S.NumRelocationTableEntries); + SwapValue(S.Flags); + SwapValue(S.Reserved1); + SwapValue(S.Reserved2); + SwapValue(S.Reserved3); } -ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { - StringRef Magic = Buffer->getBuffer().slice(0, 4); - error_code ec; - ObjectFile *Ret; - if (Magic == "\xFE\xED\xFA\xCE") - Ret = new MachOObjectFileBE32(Buffer, ec); - else if (Magic == "\xCE\xFA\xED\xFE") - Ret = new MachOObjectFileLE32(Buffer, ec); - else if (Magic == "\xFE\xED\xFA\xCF") - Ret = new MachOObjectFileBE64(Buffer, ec); - else if (Magic == "\xCF\xFA\xED\xFE") - Ret = new MachOObjectFileLE64(Buffer, ec); - else - return NULL; +template<> +void SwapStruct(macho::SymbolTableEntry &S) { + SwapValue(S.StringIndex); + SwapValue(S.Flags); + SwapValue(S.Value); +} - if (ec) - return NULL; - return Ret; +template<> +void SwapStruct(macho::Symbol64TableEntry &S) { + SwapValue(S.StringIndex); + SwapValue(S.Flags); + SwapValue(S.Value); } -/*===-- Symbols -----------------------------------------------------------===*/ +template<> +void SwapStruct(macho::Header &H) { + SwapValue(H.Magic); + SwapValue(H.CPUType); + SwapValue(H.CPUSubtype); + SwapValue(H.FileType); + SwapValue(H.NumLoadCommands); + SwapValue(H.SizeOfLoadCommands); + SwapValue(H.Flags); +} -error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb, - uint64_t &Val) const { - report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase"); +template<> +void SwapStruct(macho::SymtabLoadCommand &C) { + SwapValue(C.Type); + SwapValue(C.Size); + SwapValue(C.SymbolTableOffset); + SwapValue(C.NumSymbolTableEntries); + SwapValue(C.StringTableOffset); + SwapValue(C.StringTableSize); } -symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const { - // TODO: implement - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase"); +template<> +void SwapStruct(macho::LinkeditDataLoadCommand &C) { + SwapValue(C.Type); + SwapValue(C.Size); + SwapValue(C.DataOffset); + SwapValue(C.DataSize); } -symbol_iterator MachOObjectFileBase::end_dynamic_symbols() const { - // TODO: implement - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase"); +template<> +void SwapStruct(macho::SegmentLoadCommand &C) { + SwapValue(C.Type); + SwapValue(C.Size); + SwapValue(C.VMAddress); + SwapValue(C.VMSize); + SwapValue(C.FileOffset); + SwapValue(C.FileSize); + SwapValue(C.MaxVMProtection); + SwapValue(C.InitialVMProtection); + SwapValue(C.NumSections); + SwapValue(C.Flags); } -library_iterator MachOObjectFileBase::begin_libraries_needed() const { - // TODO: implement - report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); +template<> +void SwapStruct(macho::Segment64LoadCommand &C) { + SwapValue(C.Type); + SwapValue(C.Size); + SwapValue(C.VMAddress); + SwapValue(C.VMSize); + SwapValue(C.FileOffset); + SwapValue(C.FileSize); + SwapValue(C.MaxVMProtection); + SwapValue(C.InitialVMProtection); + SwapValue(C.NumSections); + SwapValue(C.Flags); } -library_iterator MachOObjectFileBase::end_libraries_needed() const { - // TODO: implement - report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); +static bool isSwappedEndian(const MachOObjectFile *O) { + return O->isLittleEndian() != sys::IsLittleEndianHost; } -StringRef MachOObjectFileBase::getLoadName() const { - // TODO: Implement - report_fatal_error("get_load_name() unimplemented in MachOObjectFileBase"); +static macho::SegmentLoadCommand +getSegmentLoadCommand(const MachOObjectFile *O, + const MachOObjectFile::LoadCommandInfo &L) { + macho::SegmentLoadCommand Cmd; + memcpy(&Cmd, L.Ptr, sizeof(macho::SegmentLoadCommand)); + if (isSwappedEndian(O)) + SwapStruct(Cmd); + return Cmd; +} + +static macho::Segment64LoadCommand +getSegment64LoadCommand(const MachOObjectFile *O, + const MachOObjectFile::LoadCommandInfo &L) { + macho::Segment64LoadCommand Cmd; + memcpy(&Cmd, L.Ptr, sizeof(macho::Segment64LoadCommand)); + if (isSwappedEndian(O)) + SwapStruct(Cmd); + return Cmd; +} + +static uint32_t +getSegmentLoadCommandNumSections(const MachOObjectFile *O, + const MachOObjectFile::LoadCommandInfo &L) { + if (O->is64Bit()) { + macho::Segment64LoadCommand S = getSegment64LoadCommand(O, L); + return S.NumSections; + } + macho::SegmentLoadCommand S = getSegmentLoadCommand(O, L); + return S.NumSections; } -/*===-- Sections ----------------------------------------------------------===*/ +static const SectionBase * +getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, + unsigned Sec) { + uintptr_t CommandAddr = reinterpret_cast(L.Ptr); -std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const { - SectionList::const_iterator loc = - std::find(Sections.begin(), Sections.end(), Sec); - assert(loc != Sections.end() && "Sec is not a valid section!"); - return std::distance(Sections.begin(), loc); + bool Is64 = O->is64Bit(); + unsigned SegmentLoadSize = Is64 ? sizeof(macho::Segment64LoadCommand) : + sizeof(macho::SegmentLoadCommand); + unsigned SectionSize = Is64 ? sizeof(macho::Section64) : + sizeof(macho::Section); + + uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize; + return reinterpret_cast(SectionAddr); +} + +static const char *getPtr(const MachOObjectFile *O, size_t Offset) { + return O->getData().substr(Offset, 1).data(); +} + +static const char *getSymbolTableEntryPtr(const MachOObjectFile *O, + DataRefImpl DRI) { + macho::SymtabLoadCommand S = O->getSymtabLoadCommand(); + + unsigned Index = DRI.d.b; + + unsigned SymbolTableEntrySize = O->is64Bit() ? + sizeof(macho::Symbol64TableEntry) : + sizeof(macho::SymbolTableEntry); + + uint64_t Offset = S.SymbolTableOffset + Index * SymbolTableEntrySize; + return getPtr(O, Offset); +} + +static SymbolTableEntryBase +getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) { + const char *P = getSymbolTableEntryPtr(O, DRI); + SymbolTableEntryBase Ret; + memcpy(&Ret, P, sizeof(SymbolTableEntryBase)); + if (isSwappedEndian(O)) + SwapStruct(Ret); + + return Ret; } -StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const { +static StringRef parseSegmentOrSectionName(const char *P) { if (P[15] == 0) // Null terminated. return P; @@ -128,14 +252,470 @@ StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const { return StringRef(P, 16); } -error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI, +// Helper to advance a section or symbol iterator multiple increments at a time. +template +static error_code advance(T &it, size_t Val) { + error_code ec; + while (Val--) { + it.increment(ec); + } + return ec; +} + +template +static void advanceTo(T &it, size_t Val) { + if (error_code ec = advance(it, Val)) + report_fatal_error(ec.message()); +} + +static unsigned getCPUType(const MachOObjectFile *O) { + return O->getHeader().CPUType; +} + +static void printRelocationTargetName(const MachOObjectFile *O, + const macho::RelocationEntry &RE, + raw_string_ostream &fmt) { + bool IsScattered = O->isRelocationScattered(RE); + + // Target of a scattered relocation is an address. In the interest of + // generating pretty output, scan through the symbol table looking for a + // symbol that aligns with that address. If we find one, print it. + // Otherwise, we just print the hex address of the target. + if (IsScattered) { + uint32_t Val = O->getPlainRelocationSymbolNum(RE); + + error_code ec; + for (symbol_iterator SI = O->begin_symbols(), SE = O->end_symbols(); + SI != SE; SI.increment(ec)) { + if (ec) report_fatal_error(ec.message()); + + uint64_t Addr; + StringRef Name; + + if ((ec = SI->getAddress(Addr))) + report_fatal_error(ec.message()); + if (Addr != Val) continue; + if ((ec = SI->getName(Name))) + report_fatal_error(ec.message()); + fmt << Name; + return; + } + + // If we couldn't find a symbol that this relocation refers to, try + // to find a section beginning instead. + for (section_iterator SI = O->begin_sections(), SE = O->end_sections(); + SI != SE; SI.increment(ec)) { + if (ec) report_fatal_error(ec.message()); + + uint64_t Addr; + StringRef Name; + + if ((ec = SI->getAddress(Addr))) + report_fatal_error(ec.message()); + if (Addr != Val) continue; + if ((ec = SI->getName(Name))) + report_fatal_error(ec.message()); + fmt << Name; + return; + } + + fmt << format("0x%x", Val); + return; + } + + StringRef S; + bool isExtern = O->getPlainRelocationExternal(RE); + uint64_t Val = O->getAnyRelocationAddress(RE); + + if (isExtern) { + symbol_iterator SI = O->begin_symbols(); + advanceTo(SI, Val); + SI->getName(S); + } else { + section_iterator SI = O->begin_sections(); + advanceTo(SI, Val); + SI->getName(S); + } + + fmt << S; +} + +static uint32_t getPlainRelocationAddress(const macho::RelocationEntry &RE) { + return RE.Word0; +} + +static unsigned +getScatteredRelocationAddress(const macho::RelocationEntry &RE) { + return RE.Word0 & 0xffffff; +} + +static bool getPlainRelocationPCRel(const MachOObjectFile *O, + const macho::RelocationEntry &RE) { + if (O->isLittleEndian()) + return (RE.Word1 >> 24) & 1; + return (RE.Word1 >> 7) & 1; +} + +static bool +getScatteredRelocationPCRel(const MachOObjectFile *O, + const macho::RelocationEntry &RE) { + return (RE.Word0 >> 30) & 1; +} + +static unsigned getPlainRelocationLength(const MachOObjectFile *O, + const macho::RelocationEntry &RE) { + if (O->isLittleEndian()) + return (RE.Word1 >> 25) & 3; + return (RE.Word1 >> 5) & 3; +} + +static unsigned +getScatteredRelocationLength(const macho::RelocationEntry &RE) { + return (RE.Word0 >> 28) & 3; +} + +static unsigned getPlainRelocationType(const MachOObjectFile *O, + const macho::RelocationEntry &RE) { + if (O->isLittleEndian()) + return RE.Word1 >> 28; + return RE.Word1 & 0xf; +} + +static unsigned getScatteredRelocationType(const macho::RelocationEntry &RE) { + return (RE.Word0 >> 24) & 0xf; +} + +static uint32_t getSectionFlags(const MachOObjectFile *O, + DataRefImpl Sec) { + if (O->is64Bit()) { + macho::Section64 Sect = O->getSection64(Sec); + return Sect.Flags; + } + macho::Section Sect = O->getSection(Sec); + return Sect.Flags; +} + +MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, + bool IsLittleEndian, bool Is64bits, + error_code &ec) + : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), + SymtabLoadCmd(NULL) { + uint32_t LoadCommandCount = this->getHeader().NumLoadCommands; + macho::LoadCommandType SegmentLoadType = is64Bit() ? + macho::LCT_Segment64 : macho::LCT_Segment; + + MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo(); + for (unsigned I = 0; I < LoadCommandCount; ++I) { + if (Load.C.Type == macho::LCT_Symtab) { + assert(!SymtabLoadCmd && "Multiple symbol tables"); + SymtabLoadCmd = Load.Ptr; + } + + if (Load.C.Type == SegmentLoadType) { + uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load); + for (unsigned J = 0; J < NumSections; ++J) { + const SectionBase *Sec = getSectionBase(this, Load, J); + Sections.push_back(reinterpret_cast(Sec)); + } + } + Load = getNextLoadCommandInfo(Load); + } +} + +error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb, + SymbolRef &Res) const { + Symb.d.b++; + Res = SymbolRef(Symb, this); + return object_error::success; +} + +error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, + StringRef &Res) const { + macho::SymtabLoadCommand S = getSymtabLoadCommand(); + const char *StringTable = getPtr(this, S.StringTableOffset); + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); + const char *Start = &StringTable[Entry.StringIndex]; + Res = StringRef(Start); + return object_error::success; +} + +error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb, + uint64_t &Res) const { + if (is64Bit()) { + macho::Symbol64TableEntry Entry = getSymbol64TableEntry(Symb); + Res = Entry.Value; + } else { + macho::SymbolTableEntry Entry = getSymbolTableEntry(Symb); + Res = Entry.Value; + } + return object_error::success; +} + +error_code +MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb, + uint64_t &Res) const { + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); + getSymbolAddress(Symb, Res); + if (Entry.SectionIndex) { + uint64_t Delta; + DataRefImpl SecRel; + SecRel.d.a = Entry.SectionIndex-1; + if (is64Bit()) { + macho::Section64 Sec = getSection64(SecRel); + Delta = Sec.Offset - Sec.Address; + } else { + macho::Section Sec = getSection(SecRel); + Delta = Sec.Offset - Sec.Address; + } + + Res += Delta; + } + + return object_error::success; +} + +error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, + uint64_t &Result) const { + uint64_t BeginOffset; + uint64_t EndOffset = 0; + uint8_t SectionIndex; + + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI); + uint64_t Value; + getSymbolAddress(DRI, Value); + + BeginOffset = Value; + + SectionIndex = Entry.SectionIndex; + if (!SectionIndex) { + uint32_t flags = SymbolRef::SF_None; + this->getSymbolFlags(DRI, flags); + if (flags & SymbolRef::SF_Common) + Result = Value; + else + Result = UnknownAddressOrSize; + return object_error::success; + } + // Unfortunately symbols are unsorted so we need to touch all + // symbols from load command + macho::SymtabLoadCommand Symtab = getSymtabLoadCommand(); + DRI.d.b = 0; + while (DRI.d.b <= Symtab.NumSymbolTableEntries) { + Entry = getSymbolTableEntryBase(this, DRI); + getSymbolAddress(DRI, Value); + if (Entry.SectionIndex == SectionIndex && Value > BeginOffset) + if (!EndOffset || Value < EndOffset) + EndOffset = Value; + DRI.d.b++; + } + if (!EndOffset) { + uint64_t Size; + DataRefImpl Sec; + Sec.d.a = SectionIndex-1; + getSectionSize(Sec, Size); + getSectionAddress(Sec, EndOffset); + EndOffset += Size; + } + Result = EndOffset - BeginOffset; + return object_error::success; +} + +error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, + SymbolRef::Type &Res) const { + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); + uint8_t n_type = Entry.Type; + + Res = SymbolRef::ST_Other; + + // If this is a STAB debugging symbol, we can do nothing more. + if (n_type & MachO::NlistMaskStab) { + Res = SymbolRef::ST_Debug; + return object_error::success; + } + + switch (n_type & MachO::NlistMaskType) { + case MachO::NListTypeUndefined : + Res = SymbolRef::ST_Unknown; + break; + case MachO::NListTypeSection : + Res = SymbolRef::ST_Function; + break; + } + return object_error::success; +} + +error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl Symb, + char &Res) const { + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); + uint8_t Type = Entry.Type; + uint16_t Flags = Entry.Flags; + + char Char; + switch (Type & macho::STF_TypeMask) { + case macho::STT_Undefined: + Char = 'u'; + break; + case macho::STT_Absolute: + case macho::STT_Section: + Char = 's'; + break; + default: + Char = '?'; + break; + } + + if (Flags & (macho::STF_External | macho::STF_PrivateExtern)) + Char = toupper(static_cast(Char)); + Res = Char; + return object_error::success; +} + +error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, + uint32_t &Result) const { + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI); + + uint8_t MachOType = Entry.Type; + uint16_t MachOFlags = Entry.Flags; + + // TODO: Correctly set SF_ThreadLocal + Result = SymbolRef::SF_None; + + if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined) + Result |= SymbolRef::SF_Undefined; + + if (MachOFlags & macho::STF_StabsEntryMask) + Result |= SymbolRef::SF_FormatSpecific; + + if (MachOType & MachO::NlistMaskExternal) { + Result |= SymbolRef::SF_Global; + if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined) + Result |= SymbolRef::SF_Common; + } + + if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef)) + Result |= SymbolRef::SF_Weak; + + if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute) + Result |= SymbolRef::SF_Absolute; + + return object_error::success; +} + +error_code +MachOObjectFile::getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const { + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); + uint8_t index = Entry.SectionIndex; + + if (index == 0) { + Res = end_sections(); + } else { + DataRefImpl DRI; + DRI.d.a = index - 1; + Res = section_iterator(SectionRef(DRI, this)); + } + + return object_error::success; +} + +error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb, + uint64_t &Val) const { + report_fatal_error("getSymbolValue unimplemented in MachOObjectFile"); +} + +error_code MachOObjectFile::getSectionNext(DataRefImpl Sec, + SectionRef &Res) const { + Sec.d.a++; + Res = SectionRef(Sec, this); + return object_error::success; +} + +error_code +MachOObjectFile::getSectionName(DataRefImpl Sec, + StringRef &Result) const { + ArrayRef Raw = getSectionRawName(Sec); + Result = parseSegmentOrSectionName(Raw.data()); + return object_error::success; +} + +error_code +MachOObjectFile::getSectionAddress(DataRefImpl Sec, + uint64_t &Res) const { + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + Res = Sect.Address; + } else { + macho::Section Sect = getSection(Sec); + Res = Sect.Address; + } + return object_error::success; +} + +error_code +MachOObjectFile::getSectionSize(DataRefImpl Sec, + uint64_t &Res) const { + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + Res = Sect.Size; + } else { + macho::Section Sect = getSection(Sec); + Res = Sect.Size; + } + + return object_error::success; +} + +error_code +MachOObjectFile::getSectionContents(DataRefImpl Sec, + StringRef &Res) const { + uint32_t Offset; + uint64_t Size; + + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + Offset = Sect.Offset; + Size = Sect.Size; + } else { + macho::Section Sect =getSection(Sec); + Offset = Sect.Offset; + Size = Sect.Size; + } + + Res = this->getData().substr(Offset, Size); + return object_error::success; +} + +error_code +MachOObjectFile::getSectionAlignment(DataRefImpl Sec, + uint64_t &Res) const { + uint32_t Align; + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + Align = Sect.Align; + } else { + macho::Section Sect = getSection(Sec); + Align = Sect.Align; + } + + Res = uint64_t(1) << Align; + return object_error::success; +} + +error_code +MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const { + uint32_t Flags = getSectionFlags(this, Sec); + Res = Flags & macho::SF_PureInstructions; + return object_error::success; +} + +error_code MachOObjectFile::isSectionData(DataRefImpl DRI, bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; } -error_code MachOObjectFileBase::isSectionBSS(DataRefImpl DRI, +error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, bool &Result) const { // FIXME: Unimplemented. Result = false; @@ -143,21 +723,30 @@ error_code MachOObjectFileBase::isSectionBSS(DataRefImpl DRI, } error_code -MachOObjectFileBase::isSectionRequiredForExecution(DataRefImpl Sec, +MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec, bool &Result) const { // FIXME: Unimplemented. Result = true; return object_error::success; } -error_code MachOObjectFileBase::isSectionVirtual(DataRefImpl Sec, +error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; } -error_code MachOObjectFileBase::isSectionReadOnlyData(DataRefImpl Sec, +error_code +MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const { + uint32_t Flags = getSectionFlags(this, Sec); + unsigned SectionType = Flags & MachO::SectionFlagMaskSectionType; + Res = SectionType == MachO::SectionTypeZeroFill || + SectionType == MachO::SectionTypeZeroFillLarge; + return object_error::success; +} + +error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec, bool &Result) const { // Consider using the code from isSectionText to look for __const sections. // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS @@ -168,44 +757,752 @@ error_code MachOObjectFileBase::isSectionReadOnlyData(DataRefImpl Sec, return object_error::success; } -relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) const { +error_code +MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb, + bool &Result) const { + SymbolRef::Type ST; + this->getSymbolType(Symb, ST); + if (ST == SymbolRef::ST_Unknown) { + Result = false; + return object_error::success; + } + + uint64_t SectBegin, SectEnd; + getSectionAddress(Sec, SectBegin); + getSectionSize(Sec, SectEnd); + SectEnd += SectBegin; + + uint64_t SymAddr; + getSymbolAddress(Symb, SymAddr); + Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); + + return object_error::success; +} + +relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { DataRefImpl ret; - ret.d.b = getSectionIndex(Sec); + ret.d.b = Sec.d.a; return relocation_iterator(RelocationRef(ret, this)); } +relocation_iterator +MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { + uint32_t LastReloc; + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + LastReloc = Sect.NumRelocationTableEntries; + } else { + macho::Section Sect = getSection(Sec); + LastReloc = Sect.NumRelocationTableEntries; + } -/*===-- Relocations -------------------------------------------------------===*/ + DataRefImpl Ret; + Ret.d.a = LastReloc; + Ret.d.b = Sec.d.a; + return relocation_iterator(RelocationRef(Ret, this)); +} -error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel, +error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, RelocationRef &Res) const { ++Rel.d.a; Res = RelocationRef(Rel, this); return object_error::success; } -error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData, - LibraryRef &Res) const { - report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); +error_code +MachOObjectFile::getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const { + uint64_t SectAddress; + DataRefImpl Sec; + Sec.d.a = Rel.d.b; + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + SectAddress = Sect.Address; + } else { + macho::Section Sect = getSection(Sec); + SectAddress = Sect.Address; + } + + macho::RelocationEntry RE = getRelocation(Rel); + uint64_t RelAddr = getAnyRelocationAddress(RE); + Res = SectAddress + RelAddr; + return object_error::success; } -error_code MachOObjectFileBase::getLibraryPath(DataRefImpl LibData, - StringRef &Res) const { - report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); +error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, + uint64_t &Res) const { + macho::RelocationEntry RE = getRelocation(Rel); + Res = getAnyRelocationAddress(RE); + return object_error::success; } -error_code MachOObjectFileBase::getRelocationAdditionalInfo(DataRefImpl Rel, - int64_t &Res) const { +error_code +MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Res) const { + macho::RelocationEntry RE = getRelocation(Rel); + uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); + bool isExtern = getPlainRelocationExternal(RE); + + DataRefImpl Sym; + if (isExtern) { + Sym.d.b = SymbolIdx; + } + Res = SymbolRef(Sym, this); + return object_error::success; +} + +error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, + uint64_t &Res) const { + macho::RelocationEntry RE = getRelocation(Rel); + Res = getAnyRelocationType(RE); + return object_error::success; +} + +error_code +MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const { + StringRef res; + uint64_t RType; + getRelocationType(Rel, RType); + + unsigned Arch = this->getArch(); + + switch (Arch) { + case Triple::x86: { + static const char *const Table[] = { + "GENERIC_RELOC_VANILLA", + "GENERIC_RELOC_PAIR", + "GENERIC_RELOC_SECTDIFF", + "GENERIC_RELOC_PB_LA_PTR", + "GENERIC_RELOC_LOCAL_SECTDIFF", + "GENERIC_RELOC_TLV" }; + + if (RType > 6) + res = "Unknown"; + else + res = Table[RType]; + break; + } + case Triple::x86_64: { + static const char *const Table[] = { + "X86_64_RELOC_UNSIGNED", + "X86_64_RELOC_SIGNED", + "X86_64_RELOC_BRANCH", + "X86_64_RELOC_GOT_LOAD", + "X86_64_RELOC_GOT", + "X86_64_RELOC_SUBTRACTOR", + "X86_64_RELOC_SIGNED_1", + "X86_64_RELOC_SIGNED_2", + "X86_64_RELOC_SIGNED_4", + "X86_64_RELOC_TLV" }; + + if (RType > 9) + res = "Unknown"; + else + res = Table[RType]; + break; + } + case Triple::arm: { + static const char *const Table[] = { + "ARM_RELOC_VANILLA", + "ARM_RELOC_PAIR", + "ARM_RELOC_SECTDIFF", + "ARM_RELOC_LOCAL_SECTDIFF", + "ARM_RELOC_PB_LA_PTR", + "ARM_RELOC_BR24", + "ARM_THUMB_RELOC_BR22", + "ARM_THUMB_32BIT_BRANCH", + "ARM_RELOC_HALF", + "ARM_RELOC_HALF_SECTDIFF" }; + + if (RType > 9) + res = "Unknown"; + else + res = Table[RType]; + break; + } + case Triple::ppc: { + static const char *const Table[] = { + "PPC_RELOC_VANILLA", + "PPC_RELOC_PAIR", + "PPC_RELOC_BR14", + "PPC_RELOC_BR24", + "PPC_RELOC_HI16", + "PPC_RELOC_LO16", + "PPC_RELOC_HA16", + "PPC_RELOC_LO14", + "PPC_RELOC_SECTDIFF", + "PPC_RELOC_PB_LA_PTR", + "PPC_RELOC_HI16_SECTDIFF", + "PPC_RELOC_LO16_SECTDIFF", + "PPC_RELOC_HA16_SECTDIFF", + "PPC_RELOC_JBSR", + "PPC_RELOC_LO14_SECTDIFF", + "PPC_RELOC_LOCAL_SECTDIFF" }; + + res = Table[RType]; + break; + } + case Triple::UnknownArch: + res = "Unknown"; + break; + } + Result.append(res.begin(), res.end()); + return object_error::success; +} + +error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Res) const { Res = 0; return object_error::success; } +error_code +MachOObjectFile::getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const { + macho::RelocationEntry RE = getRelocation(Rel); + + unsigned Arch = this->getArch(); + + std::string fmtbuf; + raw_string_ostream fmt(fmtbuf); + unsigned Type = this->getAnyRelocationType(RE); + bool IsPCRel = this->getAnyRelocationPCRel(RE); + + // Determine any addends that should be displayed with the relocation. + // These require decoding the relocation type, which is triple-specific. + + // X86_64 has entirely custom relocation types. + if (Arch == Triple::x86_64) { + bool isPCRel = getAnyRelocationPCRel(RE); + + switch (Type) { + case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD + case macho::RIT_X86_64_GOT: { // X86_64_RELOC_GOT + printRelocationTargetName(this, RE, fmt); + fmt << "@GOT"; + if (isPCRel) fmt << "PCREL"; + break; + } + case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR + DataRefImpl RelNext = Rel; + RelNext.d.a++; + macho::RelocationEntry RENext = getRelocation(RelNext); + + // X86_64_SUBTRACTOR must be followed by a relocation of type + // X86_64_RELOC_UNSIGNED. + // NOTE: Scattered relocations don't exist on x86_64. + unsigned RType = getAnyRelocationType(RENext); + if (RType != 0) + report_fatal_error("Expected X86_64_RELOC_UNSIGNED after " + "X86_64_RELOC_SUBTRACTOR."); + + // The X86_64_RELOC_UNSIGNED contains the minuend symbol, + // X86_64_SUBTRACTOR contains to the subtrahend. + printRelocationTargetName(this, RENext, fmt); + fmt << "-"; + printRelocationTargetName(this, RE, fmt); + break; + } + case macho::RIT_X86_64_TLV: + printRelocationTargetName(this, RE, fmt); + fmt << "@TLV"; + if (isPCRel) fmt << "P"; + break; + case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1 + printRelocationTargetName(this, RE, fmt); + fmt << "-1"; + break; + case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2 + printRelocationTargetName(this, RE, fmt); + fmt << "-2"; + break; + case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4 + printRelocationTargetName(this, RE, fmt); + fmt << "-4"; + break; + default: + printRelocationTargetName(this, RE, fmt); + break; + } + // X86 and ARM share some relocation types in common. + } else if (Arch == Triple::x86 || Arch == Triple::arm) { + // Generic relocation types... + switch (Type) { + case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info + return object_error::success; + case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF + DataRefImpl RelNext = Rel; + RelNext.d.a++; + macho::RelocationEntry RENext = getRelocation(RelNext); -/*===-- Miscellaneous -----------------------------------------------------===*/ + // X86 sect diff's must be followed by a relocation of type + // GENERIC_RELOC_PAIR. + unsigned RType = getAnyRelocationType(RENext); -uint8_t MachOObjectFileBase::getBytesInAddress() const { + if (RType != 1) + report_fatal_error("Expected GENERIC_RELOC_PAIR after " + "GENERIC_RELOC_SECTDIFF."); + + printRelocationTargetName(this, RE, fmt); + fmt << "-"; + printRelocationTargetName(this, RENext, fmt); + break; + } + } + + if (Arch == Triple::x86) { + // All X86 relocations that need special printing were already + // handled in the generic code. + switch (Type) { + case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF + DataRefImpl RelNext = Rel; + RelNext.d.a++; + macho::RelocationEntry RENext = getRelocation(RelNext); + + // X86 sect diff's must be followed by a relocation of type + // GENERIC_RELOC_PAIR. + unsigned RType = getAnyRelocationType(RENext); + if (RType != 1) + report_fatal_error("Expected GENERIC_RELOC_PAIR after " + "GENERIC_RELOC_LOCAL_SECTDIFF."); + + printRelocationTargetName(this, RE, fmt); + fmt << "-"; + printRelocationTargetName(this, RENext, fmt); + break; + } + case macho::RIT_Generic_TLV: { + printRelocationTargetName(this, RE, fmt); + fmt << "@TLV"; + if (IsPCRel) fmt << "P"; + break; + } + default: + printRelocationTargetName(this, RE, fmt); + } + } else { // ARM-specific relocations + switch (Type) { + case macho::RIT_ARM_Half: // ARM_RELOC_HALF + case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF + // Half relocations steal a bit from the length field to encode + // whether this is an upper16 or a lower16 relocation. + bool isUpper = getAnyRelocationLength(RE) >> 1; + + if (isUpper) + fmt << ":upper16:("; + else + fmt << ":lower16:("; + printRelocationTargetName(this, RE, fmt); + + DataRefImpl RelNext = Rel; + RelNext.d.a++; + macho::RelocationEntry RENext = getRelocation(RelNext); + + // ARM half relocs must be followed by a relocation of type + // ARM_RELOC_PAIR. + unsigned RType = getAnyRelocationType(RENext); + if (RType != 1) + report_fatal_error("Expected ARM_RELOC_PAIR after " + "GENERIC_RELOC_HALF"); + + // NOTE: The half of the target virtual address is stashed in the + // address field of the secondary relocation, but we can't reverse + // engineer the constant offset from it without decoding the movw/movt + // instruction to find the other half in its immediate field. + + // ARM_RELOC_HALF_SECTDIFF encodes the second section in the + // symbol/section pointer of the follow-on relocation. + if (Type == macho::RIT_ARM_HalfDifference) { + fmt << "-"; + printRelocationTargetName(this, RENext, fmt); + } + + fmt << ")"; + break; + } + default: { + printRelocationTargetName(this, RE, fmt); + } + } + } + } else + printRelocationTargetName(this, RE, fmt); + + fmt.flush(); + Result.append(fmtbuf.begin(), fmtbuf.end()); + return object_error::success; +} + +error_code +MachOObjectFile::getRelocationHidden(DataRefImpl Rel, + bool &Result) const { + unsigned Arch = getArch(); + uint64_t Type; + getRelocationType(Rel, Type); + + Result = false; + + // On arches that use the generic relocations, GENERIC_RELOC_PAIR + // is always hidden. + if (Arch == Triple::x86 || Arch == Triple::arm) { + if (Type == macho::RIT_Pair) Result = true; + } else if (Arch == Triple::x86_64) { + // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows + // an X864_64_RELOC_SUBTRACTOR. + if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) { + DataRefImpl RelPrev = Rel; + RelPrev.d.a--; + uint64_t PrevType; + getRelocationType(RelPrev, PrevType); + if (PrevType == macho::RIT_X86_64_Subtractor) + Result = true; + } + } + + return object_error::success; +} + +error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData, + LibraryRef &Res) const { + report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); +} + +error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData, + StringRef &Res) const { + report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); +} + +symbol_iterator MachOObjectFile::begin_symbols() const { + // DRI.d.a = segment number; DRI.d.b = symbol index. + DataRefImpl DRI; + return symbol_iterator(SymbolRef(DRI, this)); +} + +symbol_iterator MachOObjectFile::end_symbols() const { + DataRefImpl DRI; + if (SymtabLoadCmd) { + macho::SymtabLoadCommand Symtab = getSymtabLoadCommand(); + DRI.d.b = Symtab.NumSymbolTableEntries; + } + return symbol_iterator(SymbolRef(DRI, this)); +} + +symbol_iterator MachOObjectFile::begin_dynamic_symbols() const { + // TODO: implement + report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile"); +} + +symbol_iterator MachOObjectFile::end_dynamic_symbols() const { + // TODO: implement + report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile"); +} + +section_iterator MachOObjectFile::begin_sections() const { + DataRefImpl DRI; + return section_iterator(SectionRef(DRI, this)); +} + +section_iterator MachOObjectFile::end_sections() const { + DataRefImpl DRI; + DRI.d.a = Sections.size(); + return section_iterator(SectionRef(DRI, this)); +} + +library_iterator MachOObjectFile::begin_libraries_needed() const { + // TODO: implement + report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); +} + +library_iterator MachOObjectFile::end_libraries_needed() const { + // TODO: implement + report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); +} + +uint8_t MachOObjectFile::getBytesInAddress() const { return is64Bit() ? 8 : 4; } +StringRef MachOObjectFile::getFileFormatName() const { + unsigned CPUType = getCPUType(this); + if (!is64Bit()) { + switch (CPUType) { + case llvm::MachO::CPUTypeI386: + return "Mach-O 32-bit i386"; + case llvm::MachO::CPUTypeARM: + return "Mach-O arm"; + case llvm::MachO::CPUTypePowerPC: + return "Mach-O 32-bit ppc"; + default: + assert((CPUType & llvm::MachO::CPUArchABI64) == 0 && + "64-bit object file when we're not 64-bit?"); + return "Mach-O 32-bit unknown"; + } + } + + // Make sure the cpu type has the correct mask. + assert((CPUType & llvm::MachO::CPUArchABI64) + == llvm::MachO::CPUArchABI64 && + "32-bit object file when we're 64-bit?"); + + switch (CPUType) { + case llvm::MachO::CPUTypeX86_64: + return "Mach-O 64-bit x86-64"; + case llvm::MachO::CPUTypePowerPC64: + return "Mach-O 64-bit ppc64"; + default: + return "Mach-O 64-bit unknown"; + } +} + +unsigned MachOObjectFile::getArch() const { + switch (getCPUType(this)) { + case llvm::MachO::CPUTypeI386: + return Triple::x86; + case llvm::MachO::CPUTypeX86_64: + return Triple::x86_64; + case llvm::MachO::CPUTypeARM: + return Triple::arm; + case llvm::MachO::CPUTypePowerPC: + return Triple::ppc; + case llvm::MachO::CPUTypePowerPC64: + return Triple::ppc64; + default: + return Triple::UnknownArch; + } +} + +StringRef MachOObjectFile::getLoadName() const { + // TODO: Implement + report_fatal_error("get_load_name() unimplemented in MachOObjectFile"); +} + +StringRef +MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { + ArrayRef Raw = getSectionRawFinalSegmentName(Sec); + return parseSegmentOrSectionName(Raw.data()); +} + +ArrayRef +MachOObjectFile::getSectionRawName(DataRefImpl Sec) const { + const SectionBase *Base = + reinterpret_cast(Sections[Sec.d.a]); + return ArrayRef(Base->Name); +} + +ArrayRef +MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { + const SectionBase *Base = + reinterpret_cast(Sections[Sec.d.a]); + return ArrayRef(Base->SegmentName); +} + +bool +MachOObjectFile::isRelocationScattered(const macho::RelocationEntry &RE) + const { + if (getCPUType(this) == llvm::MachO::CPUTypeX86_64) + return false; + return getPlainRelocationAddress(RE) & macho::RF_Scattered; +} + +unsigned MachOObjectFile::getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) const { + if (isLittleEndian()) + return RE.Word1 & 0xffffff; + return RE.Word1 >> 8; +} + +bool MachOObjectFile::getPlainRelocationExternal(const macho::RelocationEntry &RE) const { + if (isLittleEndian()) + return (RE.Word1 >> 27) & 1; + return (RE.Word1 >> 4) & 1; +} + +bool +MachOObjectFile::getScatteredRelocationScattered(const macho::RelocationEntry &RE) const { + return RE.Word0 >> 31; +} + +uint32_t +MachOObjectFile::getScatteredRelocationValue(const macho::RelocationEntry &RE) const { + return RE.Word1; +} + +unsigned +MachOObjectFile::getAnyRelocationAddress(const macho::RelocationEntry &RE) const { + if (isRelocationScattered(RE)) + return getScatteredRelocationAddress(RE); + return getPlainRelocationAddress(RE); +} + +unsigned +MachOObjectFile::getAnyRelocationPCRel(const macho::RelocationEntry &RE) const { + if (isRelocationScattered(RE)) + return getScatteredRelocationPCRel(this, RE); + return getPlainRelocationPCRel(this, RE); +} + +unsigned +MachOObjectFile::getAnyRelocationLength(const macho::RelocationEntry &RE) const { + if (isRelocationScattered(RE)) + return getScatteredRelocationLength(RE); + return getPlainRelocationLength(this, RE); +} + +unsigned +MachOObjectFile::getAnyRelocationType(const macho::RelocationEntry &RE) const { + if (isRelocationScattered(RE)) + return getScatteredRelocationType(RE); + return getPlainRelocationType(this, RE); +} + +MachOObjectFile::LoadCommandInfo +MachOObjectFile::getFirstLoadCommandInfo() const { + MachOObjectFile::LoadCommandInfo Load; + + unsigned HeaderSize = is64Bit() ? macho::Header64Size : macho::Header32Size; + Load.Ptr = getPtr(this, HeaderSize); + memcpy(&Load.C, Load.Ptr, sizeof(macho::LoadCommand)); + if (isSwappedEndian(this)) + SwapStruct(Load.C); + return Load; +} + +MachOObjectFile::LoadCommandInfo +MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const { + MachOObjectFile::LoadCommandInfo Next; + Next.Ptr = L.Ptr + L.C.Size; + memcpy(&Next.C, Next.Ptr, sizeof(macho::LoadCommand)); + if (isSwappedEndian(this)) + SwapStruct(Next.C); + return Next; +} + +macho::Section MachOObjectFile::getSection(DataRefImpl DRI) const { + const SectionBase *Addr = + reinterpret_cast(Sections[DRI.d.a]); + macho::Section Ret; + memcpy(&Ret, Addr, sizeof(macho::Section)); + if (isSwappedEndian(this)) + SwapStruct(Ret); + return Ret; +} + +macho::Section64 MachOObjectFile::getSection64(DataRefImpl DRI) const { + const SectionBase *Addr = + reinterpret_cast(Sections[DRI.d.a]); + macho::Section64 Ret; + memcpy(&Ret, Addr, sizeof(macho::Section64)); + if (isSwappedEndian(this)) + SwapStruct(Ret); + return Ret; +} + +macho::SymbolTableEntry +MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { + const char *P = getSymbolTableEntryPtr(this, DRI); + macho::SymbolTableEntry Ret; + memcpy(&Ret, P, sizeof(macho::SymbolTableEntry)); + if (isSwappedEndian(this)) + SwapStruct(Ret); + return Ret; +} + +macho::Symbol64TableEntry +MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { + const char *P = getSymbolTableEntryPtr(this, DRI); + macho::Symbol64TableEntry Ret; + memcpy(&Ret, P, sizeof(macho::Symbol64TableEntry)); + if (isSwappedEndian(this)) + SwapStruct(Ret); + return Ret; +} + +macho::LinkeditDataLoadCommand +MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandInfo &L) const { + macho::LinkeditDataLoadCommand Cmd; + memcpy(&Cmd, L.Ptr, sizeof(macho::LinkeditDataLoadCommand)); + if (isSwappedEndian(this)) + SwapStruct(Cmd); + return Cmd; +} + +macho::RelocationEntry +MachOObjectFile::getRelocation(DataRefImpl Rel) const { + uint32_t RelOffset; + DataRefImpl Sec; + Sec.d.a = Rel.d.b; + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + RelOffset = Sect.RelocationTableOffset; + } else { + macho::Section Sect = getSection(Sec); + RelOffset = Sect.RelocationTableOffset; + } + + uint64_t Offset = RelOffset + Rel.d.a * sizeof(macho::RelocationEntry); + + macho::RelocationEntry Ret; + memcpy(&Ret, getPtr(this, Offset), sizeof(macho::RelocationEntry)); + if (isSwappedEndian(this)) + SwapStruct(Ret); + + return Ret; +} + +macho::Header MachOObjectFile::getHeader() const { + macho::Header H; + memcpy(&H, getPtr(this, 0), sizeof(macho::Header)); + if (isSwappedEndian(this)) + SwapStruct(H); + return H; +} + +macho::SymtabLoadCommand +MachOObjectFile::getSymtabLoadCommand() const { + macho::SymtabLoadCommand Cmd; + memcpy(&Cmd, SymtabLoadCmd, sizeof(macho::SymtabLoadCommand)); + if (isSwappedEndian(this)) + SwapStruct(Cmd); + return Cmd; +} + +bool MachOObjectFile::is64Bit() const { + return getType() == getMachOType(false, true) || + getType() == getMachOType(true, true); +} + +void MachOObjectFile::ReadULEB128s(uint64_t Index, + SmallVectorImpl &Out) const { + DataExtractor extractor(ObjectFile::getData(), true, 0); + + uint32_t offset = Index; + uint64_t data = 0; + while (uint64_t delta = extractor.getULEB128(&offset)) { + data += delta; + Out.push_back(data); + } +} + +ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { + StringRef Magic = Buffer->getBuffer().slice(0, 4); + error_code ec; + ObjectFile *Ret; + if (Magic == "\xFE\xED\xFA\xCE") + Ret = new MachOObjectFile(Buffer, false, false, ec); + else if (Magic == "\xCE\xFA\xED\xFE") + Ret = new MachOObjectFile(Buffer, true, false, ec); + else if (Magic == "\xFE\xED\xFA\xCF") + Ret = new MachOObjectFile(Buffer, false, true, ec); + else if (Magic == "\xCF\xFA\xED\xFE") + Ret = new MachOObjectFile(Buffer, true, true, ec); + else + return NULL; + + if (ec) + return NULL; + return Ret; +} + } // end namespace object } // end namespace llvm -- cgit v1.2.3 From db5f9270207292b62ea847560c5dd4e9873b57f5 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 19 Apr 2013 11:36:47 +0000 Subject: Don't read one command past the end. Thanks to Evgeniy Stepanov for reporting this. It might be a good idea to add a command iterator abstraction to MachO.h, but this fixes the bug for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179848 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index f5910dd95d..d26eb2ce61 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -405,7 +405,7 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, macho::LCT_Segment64 : macho::LCT_Segment; MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo(); - for (unsigned I = 0; I < LoadCommandCount; ++I) { + for (unsigned I = 0; ; ++I) { if (Load.C.Type == macho::LCT_Symtab) { assert(!SymtabLoadCmd && "Multiple symbol tables"); SymtabLoadCmd = Load.Ptr; @@ -418,7 +418,11 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, Sections.push_back(reinterpret_cast(Sec)); } } - Load = getNextLoadCommandInfo(Load); + + if (I == LoadCommandCount - 1) + break; + else + Load = getNextLoadCommandInfo(Load); } } -- cgit v1.2.3 From 143d223447cb55ae08d313078f7a5917873247ae Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 19 Apr 2013 13:45:05 +0000 Subject: refactor the struct byte swapping to a helper function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179851 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 90 ++++++++++-------------------------------- 1 file changed, 20 insertions(+), 70 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index d26eb2ce61..2f5048688c 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -165,28 +165,25 @@ void SwapStruct(macho::Segment64LoadCommand &C) { SwapValue(C.Flags); } -static bool isSwappedEndian(const MachOObjectFile *O) { - return O->isLittleEndian() != sys::IsLittleEndianHost; +template +T getStruct(const MachOObjectFile *O, const char *P) { + T Cmd; + memcpy(&Cmd, P, sizeof(T)); + if (O->isLittleEndian() != sys::IsLittleEndianHost) + SwapStruct(Cmd); + return Cmd; } static macho::SegmentLoadCommand getSegmentLoadCommand(const MachOObjectFile *O, const MachOObjectFile::LoadCommandInfo &L) { - macho::SegmentLoadCommand Cmd; - memcpy(&Cmd, L.Ptr, sizeof(macho::SegmentLoadCommand)); - if (isSwappedEndian(O)) - SwapStruct(Cmd); - return Cmd; + return getStruct(O, L.Ptr); } static macho::Segment64LoadCommand getSegment64LoadCommand(const MachOObjectFile *O, const MachOObjectFile::LoadCommandInfo &L) { - macho::Segment64LoadCommand Cmd; - memcpy(&Cmd, L.Ptr, sizeof(macho::Segment64LoadCommand)); - if (isSwappedEndian(O)) - SwapStruct(Cmd); - return Cmd; + return getStruct(O, L.Ptr); } static uint32_t @@ -236,12 +233,7 @@ static const char *getSymbolTableEntryPtr(const MachOObjectFile *O, static SymbolTableEntryBase getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) { const char *P = getSymbolTableEntryPtr(O, DRI); - SymbolTableEntryBase Ret; - memcpy(&Ret, P, sizeof(SymbolTableEntryBase)); - if (isSwappedEndian(O)) - SwapStruct(Ret); - - return Ret; + return getStruct(O, P); } static StringRef parseSegmentOrSectionName(const char *P) { @@ -1366,9 +1358,7 @@ MachOObjectFile::getFirstLoadCommandInfo() const { unsigned HeaderSize = is64Bit() ? macho::Header64Size : macho::Header32Size; Load.Ptr = getPtr(this, HeaderSize); - memcpy(&Load.C, Load.Ptr, sizeof(macho::LoadCommand)); - if (isSwappedEndian(this)) - SwapStruct(Load.C); + Load.C = getStruct(this, Load.Ptr); return Load; } @@ -1376,59 +1366,33 @@ MachOObjectFile::LoadCommandInfo MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const { MachOObjectFile::LoadCommandInfo Next; Next.Ptr = L.Ptr + L.C.Size; - memcpy(&Next.C, Next.Ptr, sizeof(macho::LoadCommand)); - if (isSwappedEndian(this)) - SwapStruct(Next.C); + Next.C = getStruct(this, Next.Ptr); return Next; } macho::Section MachOObjectFile::getSection(DataRefImpl DRI) const { - const SectionBase *Addr = - reinterpret_cast(Sections[DRI.d.a]); - macho::Section Ret; - memcpy(&Ret, Addr, sizeof(macho::Section)); - if (isSwappedEndian(this)) - SwapStruct(Ret); - return Ret; + return getStruct(this, Sections[DRI.d.a]); } macho::Section64 MachOObjectFile::getSection64(DataRefImpl DRI) const { - const SectionBase *Addr = - reinterpret_cast(Sections[DRI.d.a]); - macho::Section64 Ret; - memcpy(&Ret, Addr, sizeof(macho::Section64)); - if (isSwappedEndian(this)) - SwapStruct(Ret); - return Ret; + return getStruct(this, Sections[DRI.d.a]); } macho::SymbolTableEntry MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { const char *P = getSymbolTableEntryPtr(this, DRI); - macho::SymbolTableEntry Ret; - memcpy(&Ret, P, sizeof(macho::SymbolTableEntry)); - if (isSwappedEndian(this)) - SwapStruct(Ret); - return Ret; + return getStruct(this, P); } macho::Symbol64TableEntry MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { const char *P = getSymbolTableEntryPtr(this, DRI); - macho::Symbol64TableEntry Ret; - memcpy(&Ret, P, sizeof(macho::Symbol64TableEntry)); - if (isSwappedEndian(this)) - SwapStruct(Ret); - return Ret; + return getStruct(this, P); } macho::LinkeditDataLoadCommand MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandInfo &L) const { - macho::LinkeditDataLoadCommand Cmd; - memcpy(&Cmd, L.Ptr, sizeof(macho::LinkeditDataLoadCommand)); - if (isSwappedEndian(this)) - SwapStruct(Cmd); - return Cmd; + return getStruct(this, L.Ptr); } macho::RelocationEntry @@ -1445,30 +1409,16 @@ MachOObjectFile::getRelocation(DataRefImpl Rel) const { } uint64_t Offset = RelOffset + Rel.d.a * sizeof(macho::RelocationEntry); - - macho::RelocationEntry Ret; - memcpy(&Ret, getPtr(this, Offset), sizeof(macho::RelocationEntry)); - if (isSwappedEndian(this)) - SwapStruct(Ret); - - return Ret; + return getStruct(this, getPtr(this, Offset)); } macho::Header MachOObjectFile::getHeader() const { - macho::Header H; - memcpy(&H, getPtr(this, 0), sizeof(macho::Header)); - if (isSwappedEndian(this)) - SwapStruct(H); - return H; + return getStruct(this, getPtr(this, 0)); } macho::SymtabLoadCommand MachOObjectFile::getSymtabLoadCommand() const { - macho::SymtabLoadCommand Cmd; - memcpy(&Cmd, SymtabLoadCmd, sizeof(macho::SymtabLoadCommand)); - if (isSwappedEndian(this)) - SwapStruct(Cmd); - return Cmd; + return getStruct(this, SymtabLoadCmd); } bool MachOObjectFile::is64Bit() const { -- cgit v1.2.3 From 709d2fdb11a623ab2dd3b0a3754d09ad0f91b7e2 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 24 Apr 2013 15:02:03 +0000 Subject: Use a pointer as the relocation iterator. Since the relocation iterator walks only the relocations in one section, we can just use a pointer and avoid fetching information about the section at every reference. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180189 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 51 +++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 2f5048688c..08570f1314 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -777,31 +777,47 @@ MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, } relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { - DataRefImpl ret; - ret.d.b = Sec.d.a; - return relocation_iterator(RelocationRef(ret, this)); + uint32_t Offset; + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + Offset = Sect.RelocationTableOffset; + } else { + macho::Section Sect = getSection(Sec); + Offset = Sect.RelocationTableOffset; + } + + DataRefImpl Ret; + Ret.p = reinterpret_cast(getPtr(this, Offset)); + return relocation_iterator(RelocationRef(Ret, this)); } relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { - uint32_t LastReloc; + uint32_t Offset; + uint32_t Num; if (is64Bit()) { macho::Section64 Sect = getSection64(Sec); - LastReloc = Sect.NumRelocationTableEntries; + Offset = Sect.RelocationTableOffset; + Num = Sect.NumRelocationTableEntries; } else { macho::Section Sect = getSection(Sec); - LastReloc = Sect.NumRelocationTableEntries; + Offset = Sect.RelocationTableOffset; + Num = Sect.NumRelocationTableEntries; } + const macho::RelocationEntry *P = + reinterpret_cast(getPtr(this, Offset)); + DataRefImpl Ret; - Ret.d.a = LastReloc; - Ret.d.b = Sec.d.a; + Ret.p = reinterpret_cast(P + Num); return relocation_iterator(RelocationRef(Ret, this)); } error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, - RelocationRef &Res) const { - ++Rel.d.a; + RelocationRef &Res) const { + const macho::RelocationEntry *P = + reinterpret_cast(Rel.p); + Rel.p = reinterpret_cast(P + 1); Res = RelocationRef(Rel, this); return object_error::success; } @@ -1397,19 +1413,8 @@ MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandIn macho::RelocationEntry MachOObjectFile::getRelocation(DataRefImpl Rel) const { - uint32_t RelOffset; - DataRefImpl Sec; - Sec.d.a = Rel.d.b; - if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - RelOffset = Sect.RelocationTableOffset; - } else { - macho::Section Sect = getSection(Sec); - RelOffset = Sect.RelocationTableOffset; - } - - uint64_t Offset = RelOffset + Rel.d.a * sizeof(macho::RelocationEntry); - return getStruct(this, getPtr(this, Offset)); + const char *P = reinterpret_cast(Rel.p); + return getStruct(this, P); } macho::Header MachOObjectFile::getHeader() const { -- cgit v1.2.3 From f69a81f001613b834960bae69cd6099265cc4d98 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 24 Apr 2013 15:14:22 +0000 Subject: Formatting fixes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180190 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 51 +++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 08570f1314..e4b3350843 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -615,7 +615,7 @@ MachOObjectFile::getSymbolSection(DataRefImpl Symb, } error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb, - uint64_t &Val) const { + uint64_t &Val) const { report_fatal_error("getSymbolValue unimplemented in MachOObjectFile"); } @@ -627,16 +627,14 @@ error_code MachOObjectFile::getSectionNext(DataRefImpl Sec, } error_code -MachOObjectFile::getSectionName(DataRefImpl Sec, - StringRef &Result) const { +MachOObjectFile::getSectionName(DataRefImpl Sec, StringRef &Result) const { ArrayRef Raw = getSectionRawName(Sec); Result = parseSegmentOrSectionName(Raw.data()); return object_error::success; } error_code -MachOObjectFile::getSectionAddress(DataRefImpl Sec, - uint64_t &Res) const { +MachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const { if (is64Bit()) { macho::Section64 Sect = getSection64(Sec); Res = Sect.Address; @@ -648,8 +646,7 @@ MachOObjectFile::getSectionAddress(DataRefImpl Sec, } error_code -MachOObjectFile::getSectionSize(DataRefImpl Sec, - uint64_t &Res) const { +MachOObjectFile::getSectionSize(DataRefImpl Sec, uint64_t &Res) const { if (is64Bit()) { macho::Section64 Sect = getSection64(Sec); Res = Sect.Size; @@ -662,8 +659,7 @@ MachOObjectFile::getSectionSize(DataRefImpl Sec, } error_code -MachOObjectFile::getSectionContents(DataRefImpl Sec, - StringRef &Res) const { +MachOObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Res) const { uint32_t Offset; uint64_t Size; @@ -682,8 +678,7 @@ MachOObjectFile::getSectionContents(DataRefImpl Sec, } error_code -MachOObjectFile::getSectionAlignment(DataRefImpl Sec, - uint64_t &Res) const { +MachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const { uint32_t Align; if (is64Bit()) { macho::Section64 Sect = getSection64(Sec); @@ -704,15 +699,13 @@ MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const { return object_error::success; } -error_code MachOObjectFile::isSectionData(DataRefImpl DRI, - bool &Result) const { +error_code MachOObjectFile::isSectionData(DataRefImpl DRI, bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; } -error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, - bool &Result) const { +error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; @@ -720,14 +713,14 @@ error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, error_code MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec, - bool &Result) const { + bool &Result) const { // FIXME: Unimplemented. Result = true; return object_error::success; } error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, - bool &Result) const { + bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; @@ -743,7 +736,7 @@ MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const { } error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec, - bool &Result) const { + bool &Result) const { // Consider using the code from isSectionText to look for __const sections. // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS // to use section attributes to distinguish code from data. @@ -754,8 +747,7 @@ error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec, } error_code -MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb, +MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const { SymbolRef::Type ST; this->getSymbolType(Symb, ST); @@ -823,8 +815,7 @@ error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, } error_code -MachOObjectFile::getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const { +MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { uint64_t SectAddress; DataRefImpl Sec; Sec.d.a = Rel.d.b; @@ -843,15 +834,14 @@ MachOObjectFile::getRelocationAddress(DataRefImpl Rel, } error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, - uint64_t &Res) const { + uint64_t &Res) const { macho::RelocationEntry RE = getRelocation(Rel); Res = getAnyRelocationAddress(RE); return object_error::success; } error_code -MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, - SymbolRef &Res) const { +MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const { macho::RelocationEntry RE = getRelocation(Rel); uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); bool isExtern = getPlainRelocationExternal(RE); @@ -865,7 +855,7 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, } error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, - uint64_t &Res) const { + uint64_t &Res) const { macho::RelocationEntry RE = getRelocation(Rel); Res = getAnyRelocationType(RE); return object_error::success; @@ -972,7 +962,7 @@ error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) const { + SmallVectorImpl &Result) const { macho::RelocationEntry RE = getRelocation(Rel); unsigned Arch = this->getArch(); @@ -1148,8 +1138,7 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel, } error_code -MachOObjectFile::getRelocationHidden(DataRefImpl Rel, - bool &Result) const { +MachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const { unsigned Arch = getArch(); uint64_t Type; getRelocationType(Rel, Type); @@ -1177,12 +1166,12 @@ MachOObjectFile::getRelocationHidden(DataRefImpl Rel, } error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData, - LibraryRef &Res) const { + LibraryRef &Res) const { report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); } error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData, - StringRef &Res) const { + StringRef &Res) const { report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); } -- cgit v1.2.3 From 51cc82887cdd6795caaffc0ece500481b697bced Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 24 Apr 2013 16:10:49 +0000 Subject: Revert r180189. This should bring the ppc bots back. I will try to write a test that would have found the problem on a little endian system too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180194 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 53 +++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 29 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index e4b3350843..4e6e0bdada 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -769,47 +769,31 @@ MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, } relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { - uint32_t Offset; - if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - Offset = Sect.RelocationTableOffset; - } else { - macho::Section Sect = getSection(Sec); - Offset = Sect.RelocationTableOffset; - } - - DataRefImpl Ret; - Ret.p = reinterpret_cast(getPtr(this, Offset)); - return relocation_iterator(RelocationRef(Ret, this)); + DataRefImpl ret; + ret.d.b = Sec.d.a; + return relocation_iterator(RelocationRef(ret, this)); } relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { - uint32_t Offset; - uint32_t Num; + uint32_t LastReloc; if (is64Bit()) { macho::Section64 Sect = getSection64(Sec); - Offset = Sect.RelocationTableOffset; - Num = Sect.NumRelocationTableEntries; + LastReloc = Sect.NumRelocationTableEntries; } else { macho::Section Sect = getSection(Sec); - Offset = Sect.RelocationTableOffset; - Num = Sect.NumRelocationTableEntries; + LastReloc = Sect.NumRelocationTableEntries; } - const macho::RelocationEntry *P = - reinterpret_cast(getPtr(this, Offset)); - DataRefImpl Ret; - Ret.p = reinterpret_cast(P + Num); + Ret.d.a = LastReloc; + Ret.d.b = Sec.d.a; return relocation_iterator(RelocationRef(Ret, this)); } -error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, - RelocationRef &Res) const { - const macho::RelocationEntry *P = - reinterpret_cast(Rel.p); - Rel.p = reinterpret_cast(P + 1); + error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const { + ++Rel.d.a; Res = RelocationRef(Rel, this); return object_error::success; } @@ -1402,8 +1386,19 @@ MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandIn macho::RelocationEntry MachOObjectFile::getRelocation(DataRefImpl Rel) const { - const char *P = reinterpret_cast(Rel.p); - return getStruct(this, P); + uint32_t RelOffset; + DataRefImpl Sec; + Sec.d.a = Rel.d.b; + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + RelOffset = Sect.RelocationTableOffset; + } else { + macho::Section Sect = getSection(Sec); + RelOffset = Sect.RelocationTableOffset; + } + + uint64_t Offset = RelOffset + Rel.d.a * sizeof(macho::RelocationEntry); + return getStruct(this, getPtr(this, Offset)); } macho::Header MachOObjectFile::getHeader() const { -- cgit v1.2.3 From 802fe9340d032d20195b00334356cf63b303386c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 24 Apr 2013 19:47:55 +0000 Subject: Use pointers to iterate over symbols. While here, don't report a dummy symbol for relocations that don't have symbols. We used to says such relocations were for the first defined symbol, but now we return end_symbols(). The llvm-readobj output change agrees with otool. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180214 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 66 +++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 30 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 4e6e0bdada..51cd5b9a95 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -216,23 +216,9 @@ static const char *getPtr(const MachOObjectFile *O, size_t Offset) { return O->getData().substr(Offset, 1).data(); } -static const char *getSymbolTableEntryPtr(const MachOObjectFile *O, - DataRefImpl DRI) { - macho::SymtabLoadCommand S = O->getSymtabLoadCommand(); - - unsigned Index = DRI.d.b; - - unsigned SymbolTableEntrySize = O->is64Bit() ? - sizeof(macho::Symbol64TableEntry) : - sizeof(macho::SymbolTableEntry); - - uint64_t Offset = S.SymbolTableOffset + Index * SymbolTableEntrySize; - return getPtr(O, Offset); -} - static SymbolTableEntryBase getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) { - const char *P = getSymbolTableEntryPtr(O, DRI); + const char *P = reinterpret_cast(DRI.p); return getStruct(O, P); } @@ -420,7 +406,10 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const { - Symb.d.b++; + unsigned SymbolTableEntrySize = is64Bit() ? + sizeof(macho::Symbol64TableEntry) : + sizeof(macho::SymbolTableEntry); + Symb.p += SymbolTableEntrySize; Res = SymbolRef(Symb, this); return object_error::success; } @@ -494,15 +483,15 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, } // Unfortunately symbols are unsorted so we need to touch all // symbols from load command - macho::SymtabLoadCommand Symtab = getSymtabLoadCommand(); - DRI.d.b = 0; - while (DRI.d.b <= Symtab.NumSymbolTableEntries) { + error_code ec; + for (symbol_iterator I = begin_symbols(), E = end_symbols(); I != E; + I.increment(ec)) { + DataRefImpl DRI = I->getRawDataRefImpl(); Entry = getSymbolTableEntryBase(this, DRI); getSymbolAddress(DRI, Value); if (Entry.SectionIndex == SectionIndex && Value > BeginOffset) if (!EndOffset || Value < EndOffset) EndOffset = Value; - DRI.d.b++; } if (!EndOffset) { uint64_t Size; @@ -829,11 +818,18 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const { macho::RelocationEntry RE = getRelocation(Rel); uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); bool isExtern = getPlainRelocationExternal(RE); + if (!isExtern) { + Res = *end_symbols(); + return object_error::success; + } + macho::SymtabLoadCommand S = getSymtabLoadCommand(); + unsigned SymbolTableEntrySize = is64Bit() ? + sizeof(macho::Symbol64TableEntry) : + sizeof(macho::SymbolTableEntry); + uint64_t Offset = S.SymbolTableOffset + SymbolIdx * SymbolTableEntrySize; DataRefImpl Sym; - if (isExtern) { - Sym.d.b = SymbolIdx; - } + Sym.p = reinterpret_cast(getPtr(this, Offset)); Res = SymbolRef(Sym, this); return object_error::success; } @@ -1160,17 +1156,27 @@ error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData, } symbol_iterator MachOObjectFile::begin_symbols() const { - // DRI.d.a = segment number; DRI.d.b = symbol index. DataRefImpl DRI; + if (!SymtabLoadCmd) + return symbol_iterator(SymbolRef(DRI, this)); + + macho::SymtabLoadCommand Symtab = getSymtabLoadCommand(); + DRI.p = reinterpret_cast(getPtr(this, Symtab.SymbolTableOffset)); return symbol_iterator(SymbolRef(DRI, this)); } symbol_iterator MachOObjectFile::end_symbols() const { DataRefImpl DRI; - if (SymtabLoadCmd) { - macho::SymtabLoadCommand Symtab = getSymtabLoadCommand(); - DRI.d.b = Symtab.NumSymbolTableEntries; - } + if (!SymtabLoadCmd) + return symbol_iterator(SymbolRef(DRI, this)); + + macho::SymtabLoadCommand Symtab = getSymtabLoadCommand(); + unsigned SymbolTableEntrySize = is64Bit() ? + sizeof(macho::Symbol64TableEntry) : + sizeof(macho::SymbolTableEntry); + unsigned Offset = Symtab.SymbolTableOffset + + Symtab.NumSymbolTableEntries * SymbolTableEntrySize; + DRI.p = reinterpret_cast(getPtr(this, Offset)); return symbol_iterator(SymbolRef(DRI, this)); } @@ -1369,13 +1375,13 @@ macho::Section64 MachOObjectFile::getSection64(DataRefImpl DRI) const { macho::SymbolTableEntry MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { - const char *P = getSymbolTableEntryPtr(this, DRI); + const char *P = reinterpret_cast(DRI.p); return getStruct(this, P); } macho::Symbol64TableEntry MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { - const char *P = getSymbolTableEntryPtr(this, DRI); + const char *P = reinterpret_cast(DRI.p); return getStruct(this, P); } -- cgit v1.2.3 From 956ca7265c697107708468b7e1b2fd21f4185bae Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 25 Apr 2013 12:28:45 +0000 Subject: Clarify getRelocationAddress x getRelocationOffset a bit. getRelocationAddress is for dynamic libraries and executables, getRelocationOffset for relocatable objects. Mark the getRelocationAddress of COFF and MachO as not implemented yet. Add a test of ELF's. llvm-readobj -r now prints the same values as readelf -r. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180259 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 51cd5b9a95..14bca2bf90 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -789,21 +789,7 @@ MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { - uint64_t SectAddress; - DataRefImpl Sec; - Sec.d.a = Rel.d.b; - if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - SectAddress = Sect.Address; - } else { - macho::Section Sect = getSection(Sec); - SectAddress = Sect.Address; - } - - macho::RelocationEntry RE = getRelocation(Rel); - uint64_t RelAddr = getAnyRelocationAddress(RE); - Res = SectAddress + RelAddr; - return object_error::success; + report_fatal_error("getRelocationAddress not implemented in MachOObjectFile"); } error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, -- cgit v1.2.3 From e5330f77cf420d71cfd46c960387eb06edeccbf8 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 25 Apr 2013 12:45:46 +0000 Subject: Use a pointer as the relocation iterator. Since the relocation iterator walks only the relocations in one section, we can just use a pointer and avoid fetching information about the section at every reference. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180262 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 53 +++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 24 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 14bca2bf90..38198b1793 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -758,31 +758,47 @@ MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, } relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { - DataRefImpl ret; - ret.d.b = Sec.d.a; - return relocation_iterator(RelocationRef(ret, this)); + uint32_t Offset; + if (is64Bit()) { + macho::Section64 Sect = getSection64(Sec); + Offset = Sect.RelocationTableOffset; + } else { + macho::Section Sect = getSection(Sec); + Offset = Sect.RelocationTableOffset; + } + + DataRefImpl Ret; + Ret.p = reinterpret_cast(getPtr(this, Offset)); + return relocation_iterator(RelocationRef(Ret, this)); } relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { - uint32_t LastReloc; + uint32_t Offset; + uint32_t Num; if (is64Bit()) { macho::Section64 Sect = getSection64(Sec); - LastReloc = Sect.NumRelocationTableEntries; + Offset = Sect.RelocationTableOffset; + Num = Sect.NumRelocationTableEntries; } else { macho::Section Sect = getSection(Sec); - LastReloc = Sect.NumRelocationTableEntries; + Offset = Sect.RelocationTableOffset; + Num = Sect.NumRelocationTableEntries; } + const macho::RelocationEntry *P = + reinterpret_cast(getPtr(this, Offset)); + DataRefImpl Ret; - Ret.d.a = LastReloc; - Ret.d.b = Sec.d.a; + Ret.p = reinterpret_cast(P + Num); return relocation_iterator(RelocationRef(Ret, this)); } - error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, - RelocationRef &Res) const { - ++Rel.d.a; +error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const { + const macho::RelocationEntry *P = + reinterpret_cast(Rel.p); + Rel.p = reinterpret_cast(P + 1); Res = RelocationRef(Rel, this); return object_error::success; } @@ -1378,19 +1394,8 @@ MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandIn macho::RelocationEntry MachOObjectFile::getRelocation(DataRefImpl Rel) const { - uint32_t RelOffset; - DataRefImpl Sec; - Sec.d.a = Rel.d.b; - if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - RelOffset = Sect.RelocationTableOffset; - } else { - macho::Section Sect = getSection(Sec); - RelOffset = Sect.RelocationTableOffset; - } - - uint64_t Offset = RelOffset + Rel.d.a * sizeof(macho::RelocationEntry); - return getStruct(this, getPtr(this, Offset)); + const char *P = reinterpret_cast(Rel.p); + return getStruct(this, P); } macho::Header MachOObjectFile::getHeader() const { -- cgit v1.2.3 From 2173e1839c2d00f7f980450dd537047b7b376e6b Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 26 Apr 2013 20:07:33 +0000 Subject: Use llvm/Object/MachO.h in macho-dumper. Drop the old macho parser. For Mach-O there were 2 implementations for parsing object files. A standalone llvm/Object/MachOObject.h and llvm/Object/MachO.h which implements the generic interface in llvm/Object/ObjectFile.h. This patch adds the missing features to MachO.h, moves macho-dump to use MachO.h and removes ObjectFile.h. In addition to making sure that check-all is clean, I checked that the new version produces exactly the same output in all Mach-O files in a llvm+clang build directory (including executables and shared libraries). To test the performance, I ran macho-dump over all the files in a llvm+clang build directory again, but this time redirecting the output to /dev/null. Both the old and new versions take about 4.6 seconds (2.5 user) to finish. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180624 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 161 +++++++++++++++++++++++++++++++++-------- 1 file changed, 132 insertions(+), 29 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 38198b1793..bb6ca93176 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -119,6 +119,11 @@ void SwapStruct(macho::Header &H) { SwapValue(H.Flags); } +template<> +void SwapStruct(macho::Header64Ext &E) { + SwapValue(E.Reserved); +} + template<> void SwapStruct(macho::SymtabLoadCommand &C) { SwapValue(C.Type); @@ -129,6 +134,30 @@ void SwapStruct(macho::SymtabLoadCommand &C) { SwapValue(C.StringTableSize); } +template<> +void SwapStruct(macho::DysymtabLoadCommand &C) { + SwapValue(C.Type); + SwapValue(C.Size); + SwapValue(C.LocalSymbolsIndex); + SwapValue(C.NumLocalSymbols); + SwapValue(C.ExternalSymbolsIndex); + SwapValue(C.NumExternalSymbols); + SwapValue(C.UndefinedSymbolsIndex); + SwapValue(C.NumUndefinedSymbols); + SwapValue(C.TOCOffset); + SwapValue(C.NumTOCEntries); + SwapValue(C.ModuleTableOffset); + SwapValue(C.NumModuleTableEntries); + SwapValue(C.ReferenceSymbolTableOffset); + SwapValue(C.NumReferencedSymbolTableEntries); + SwapValue(C.IndirectSymbolTableOffset); + SwapValue(C.NumIndirectSymbolTableEntries); + SwapValue(C.ExternalRelocationTableOffset); + SwapValue(C.NumExternalRelocationTableEntries); + SwapValue(C.LocalRelocationTableOffset); + SwapValue(C.NumLocalRelocationTableEntries); +} + template<> void SwapStruct(macho::LinkeditDataLoadCommand &C) { SwapValue(C.Type); @@ -165,6 +194,25 @@ void SwapStruct(macho::Segment64LoadCommand &C) { SwapValue(C.Flags); } +template<> +void SwapStruct(macho::IndirectSymbolTableEntry &C) { + SwapValue(C.Index); +} + +template<> +void SwapStruct(macho::LinkerOptionsLoadCommand &C) { + SwapValue(C.Type); + SwapValue(C.Size); + SwapValue(C.Count); +} + +template<> +void SwapStruct(macho::DataInCodeTableEntry &C) { + SwapValue(C.Offset); + SwapValue(C.Length); + SwapValue(C.Kind); +} + template T getStruct(const MachOObjectFile *O, const char *P) { T Cmd; @@ -174,32 +222,20 @@ T getStruct(const MachOObjectFile *O, const char *P) { return Cmd; } -static macho::SegmentLoadCommand -getSegmentLoadCommand(const MachOObjectFile *O, - const MachOObjectFile::LoadCommandInfo &L) { - return getStruct(O, L.Ptr); -} - -static macho::Segment64LoadCommand -getSegment64LoadCommand(const MachOObjectFile *O, - const MachOObjectFile::LoadCommandInfo &L) { - return getStruct(O, L.Ptr); -} - static uint32_t getSegmentLoadCommandNumSections(const MachOObjectFile *O, const MachOObjectFile::LoadCommandInfo &L) { if (O->is64Bit()) { - macho::Segment64LoadCommand S = getSegment64LoadCommand(O, L); + macho::Segment64LoadCommand S = O->getSegment64LoadCommand(L); return S.NumSections; } - macho::SegmentLoadCommand S = getSegmentLoadCommand(O, L); + macho::SegmentLoadCommand S = O->getSegmentLoadCommand(L); return S.NumSections; } -static const SectionBase * -getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, - unsigned Sec) { +static const char * +getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, + unsigned Sec) { uintptr_t CommandAddr = reinterpret_cast(L.Ptr); bool Is64 = O->is64Bit(); @@ -209,7 +245,7 @@ getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, sizeof(macho::Section); uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize; - return reinterpret_cast(SectionAddr); + return reinterpret_cast(SectionAddr); } static const char *getPtr(const MachOObjectFile *O, size_t Offset) { @@ -377,7 +413,7 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64bits, error_code &ec) : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), - SymtabLoadCmd(NULL) { + SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL) { uint32_t LoadCommandCount = this->getHeader().NumLoadCommands; macho::LoadCommandType SegmentLoadType = is64Bit() ? macho::LCT_Segment64 : macho::LCT_Segment; @@ -387,13 +423,14 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, if (Load.C.Type == macho::LCT_Symtab) { assert(!SymtabLoadCmd && "Multiple symbol tables"); SymtabLoadCmd = Load.Ptr; - } - - if (Load.C.Type == SegmentLoadType) { + } else if (Load.C.Type == macho::LCT_Dysymtab) { + assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables"); + DysymtabLoadCmd = Load.Ptr; + } else if (Load.C.Type == SegmentLoadType) { uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load); for (unsigned J = 0; J < NumSections; ++J) { - const SectionBase *Sec = getSectionBase(this, Load, J); - Sections.push_back(reinterpret_cast(Sec)); + const char *Sec = getSectionPtr(this, Load, J); + Sections.push_back(Sec); } } @@ -416,10 +453,9 @@ error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb, error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, StringRef &Res) const { - macho::SymtabLoadCommand S = getSymtabLoadCommand(); - const char *StringTable = getPtr(this, S.StringTableOffset); + StringRef StringTable = getStringTableData(); SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); - const char *Start = &StringTable[Entry.StringIndex]; + const char *Start = &StringTable.data()[Entry.StringIndex]; Res = StringRef(Start); return object_error::success; } @@ -1271,6 +1307,18 @@ StringRef MachOObjectFile::getLoadName() const { report_fatal_error("get_load_name() unimplemented in MachOObjectFile"); } +relocation_iterator MachOObjectFile::getSectionRelBegin(unsigned Index) const { + DataRefImpl DRI; + DRI.d.a = Index; + return getSectionRelBegin(DRI); +} + +relocation_iterator MachOObjectFile::getSectionRelEnd(unsigned Index) const { + DataRefImpl DRI; + DRI.d.a = Index; + return getSectionRelEnd(DRI); +} + StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { ArrayRef Raw = getSectionRawFinalSegmentName(Sec); @@ -1375,6 +1423,18 @@ macho::Section64 MachOObjectFile::getSection64(DataRefImpl DRI) const { return getStruct(this, Sections[DRI.d.a]); } +macho::Section MachOObjectFile::getSection(const LoadCommandInfo &L, + unsigned Index) const { + const char *Sec = getSectionPtr(this, L, Index); + return getStruct(this, Sec); +} + +macho::Section64 MachOObjectFile::getSection64(const LoadCommandInfo &L, + unsigned Index) const { + const char *Sec = getSectionPtr(this, L, Index); + return getStruct(this, Sec); +} + macho::SymbolTableEntry MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { const char *P = reinterpret_cast(DRI.p); @@ -1392,6 +1452,21 @@ MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandIn return getStruct(this, L.Ptr); } +macho::SegmentLoadCommand +MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); +} + +macho::Segment64LoadCommand +MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); +} + +macho::LinkerOptionsLoadCommand +MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); +} + macho::RelocationEntry MachOObjectFile::getRelocation(DataRefImpl Rel) const { const char *P = reinterpret_cast(Rel.p); @@ -1402,11 +1477,39 @@ macho::Header MachOObjectFile::getHeader() const { return getStruct(this, getPtr(this, 0)); } -macho::SymtabLoadCommand -MachOObjectFile::getSymtabLoadCommand() const { +macho::Header64Ext MachOObjectFile::getHeader64Ext() const { + return + getStruct(this, getPtr(this, sizeof(macho::Header))); +} + +macho::IndirectSymbolTableEntry MachOObjectFile::getIndirectSymbolTableEntry( + const macho::DysymtabLoadCommand &DLC, + unsigned Index) const { + uint64_t Offset = DLC.IndirectSymbolTableOffset + + Index * sizeof(macho::IndirectSymbolTableEntry); + return getStruct(this, getPtr(this, Offset)); +} + +macho::DataInCodeTableEntry +MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset, + unsigned Index) const { + uint64_t Offset = DataOffset + Index * sizeof(macho::DataInCodeTableEntry); + return getStruct(this, getPtr(this, Offset)); +} + +macho::SymtabLoadCommand MachOObjectFile::getSymtabLoadCommand() const { return getStruct(this, SymtabLoadCmd); } +macho::DysymtabLoadCommand MachOObjectFile::getDysymtabLoadCommand() const { + return getStruct(this, DysymtabLoadCmd); +} + +StringRef MachOObjectFile::getStringTableData() const { + macho::SymtabLoadCommand S = getSymtabLoadCommand(); + return getData().substr(S.StringTableOffset, S.StringTableSize); +} + bool MachOObjectFile::is64Bit() const { return getType() == getMachOType(false, true) || getType() == getMachOType(true, true); -- cgit v1.2.3 From 59a0e79631ed851d98cf9c2ba6fa5f9aafdfdc93 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 29 Apr 2013 22:24:22 +0000 Subject: Add getSymbolAlignment to the ObjectFile interface. For regular object files this is only meaningful for common symbols. An object file format with direct support for atoms should be able to provide alignment information for all symbols. This replaces getCommonSymbolAlignment and fixes test-common-symbols-alignment.ll on darwin. This also includes a fix to MachOObjectFile::getSymbolFlags. It was marking undefined symbols as common (already tested by existing mcjit tests now that it is used). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180736 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index bb6ca93176..f6840b8c15 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -495,6 +495,19 @@ MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb, return object_error::success; } +error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI, + uint32_t &Result) const { + uint32_t flags; + this->getSymbolFlags(DRI, flags); + if (flags & SymbolRef::SF_Common) { + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI); + Result = 1 << MachO::GET_COMM_ALIGN(Entry.Flags); + } else { + Result = 0; + } + return object_error::success; +} + error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, uint64_t &Result) const { uint64_t BeginOffset; @@ -609,8 +622,12 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, if (MachOType & MachO::NlistMaskExternal) { Result |= SymbolRef::SF_Global; - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined) - Result |= SymbolRef::SF_Common; + if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined) { + uint64_t Value; + getSymbolAddress(DRI, Value); + if (Value) + Result |= SymbolRef::SF_Common; + } } if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef)) -- cgit v1.2.3 From e87dadc44b1544c35e13cf48dfe167109929a944 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 30 Apr 2013 15:40:54 +0000 Subject: Fix Addend computation for non external relocations on Macho. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180790 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/MachOObjectFile.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib/Object/MachOObjectFile.cpp') diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index f6840b8c15..dfd8d3d3dd 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -1414,6 +1414,16 @@ MachOObjectFile::getAnyRelocationType(const macho::RelocationEntry &RE) const { return getPlainRelocationType(this, RE); } +SectionRef +MachOObjectFile::getRelocationSection(const macho::RelocationEntry &RE) const { + if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) + return *end_sections(); + unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1; + DataRefImpl DRI; + DRI.d.a = SecNum; + return SectionRef(DRI, this); +} + MachOObjectFile::LoadCommandInfo MachOObjectFile::getFirstLoadCommandInfo() const { MachOObjectFile::LoadCommandInfo Load; -- cgit v1.2.3