summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Object/MachOObjectFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Object/MachOObjectFile.cpp')
-rw-r--r--contrib/llvm/lib/Object/MachOObjectFile.cpp104
1 files changed, 67 insertions, 37 deletions
diff --git a/contrib/llvm/lib/Object/MachOObjectFile.cpp b/contrib/llvm/lib/Object/MachOObjectFile.cpp
index 45aeaac..6501df9 100644
--- a/contrib/llvm/lib/Object/MachOObjectFile.cpp
+++ b/contrib/llvm/lib/Object/MachOObjectFile.cpp
@@ -12,12 +12,11 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/Triple.h"
#include "llvm/Object/MachO.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Object/MachOFormat.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
-
#include <cctype>
#include <cstring>
#include <limits>
@@ -50,7 +49,15 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
MachOObject *MachOObj = MachOObject::LoadFromBuffer(Buffer, &Err);
if (!MachOObj)
return NULL;
- return new MachOObjectFile(Buffer, MachOObj, ec);
+ // 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);
}
/*===-- Symbols -----------------------------------------------------------===*/
@@ -266,7 +273,7 @@ error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI,
}
if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
- Char = toupper(Char);
+ Char = toupper(static_cast<unsigned char>(Char));
Result = Char;
return object_error::success;
}
@@ -440,9 +447,7 @@ error_code MachOObjectFile::getSectionNext(DataRefImpl DRI,
void
MachOObjectFile::getSection(DataRefImpl DRI,
InMemoryStruct<macho::Section> &Res) const {
- InMemoryStruct<macho::SegmentLoadCommand> SLC;
LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
- MachOObj->ReadSegmentLoadCommand(LCI, SLC);
MachOObj->ReadSection(LCI, DRI.d.b, Res);
}
@@ -456,9 +461,7 @@ std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
void
MachOObjectFile::getSection64(DataRefImpl DRI,
InMemoryStruct<macho::Section64> &Res) const {
- InMemoryStruct<macho::Segment64LoadCommand> SLC;
LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
- MachOObj->ReadSegment64LoadCommand(LCI, SLC);
MachOObj->ReadSection64(LCI, DRI.d.b, Res);
}
@@ -470,38 +473,61 @@ static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) {
return false;
}
+static StringRef parseSegmentOrSectionName(const char *P) {
+ if (P[15] == 0)
+ // Null terminated.
+ return P;
+ // Not null terminated, so this is a 16 char string.
+ return StringRef(P, 16);
+}
+
error_code MachOObjectFile::getSectionName(DataRefImpl DRI,
StringRef &Result) const {
- // FIXME: thread safety.
- static char result[34];
- if (is64BitLoadCommand(MachOObj, DRI)) {
- InMemoryStruct<macho::Segment64LoadCommand> SLC;
+ if (is64BitLoadCommand(MachOObj.get(), DRI)) {
LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
- MachOObj->ReadSegment64LoadCommand(LCI, SLC);
- InMemoryStruct<macho::Section64> Sect;
- MachOObj->ReadSection64(LCI, DRI.d.b, Sect);
-
- strcpy(result, Sect->SegmentName);
- strcat(result, ",");
- strcat(result, Sect->Name);
+ 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<const macho::Section64*>(Data.data());
+ Result = parseSegmentOrSectionName(sec->Name);
} else {
- InMemoryStruct<macho::SegmentLoadCommand> SLC;
LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
- MachOObj->ReadSegmentLoadCommand(LCI, SLC);
- InMemoryStruct<macho::Section> Sect;
- MachOObj->ReadSection(LCI, DRI.d.b, Sect);
+ 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<const macho::Section*>(Data.data());
+ Result = parseSegmentOrSectionName(sec->Name);
+ }
+ return object_error::success;
+}
- strcpy(result, Sect->SegmentName);
- strcat(result, ",");
- strcat(result, Sect->Name);
+error_code MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec,
+ StringRef &Res) 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<const macho::Section64*>(Data.data());
+ Res = parseSegmentOrSectionName(sec->SegmentName);
+ } 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<const macho::Section*>(Data.data());
+ Res = parseSegmentOrSectionName(sec->SegmentName);
}
- Result = StringRef(result);
return object_error::success;
}
error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI,
uint64_t &Result) const {
- if (is64BitLoadCommand(MachOObj, DRI)) {
+ if (is64BitLoadCommand(MachOObj.get(), DRI)) {
InMemoryStruct<macho::Section64> Sect;
getSection64(DRI, Sect);
Result = Sect->Address;
@@ -515,7 +541,7 @@ error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI,
error_code MachOObjectFile::getSectionSize(DataRefImpl DRI,
uint64_t &Result) const {
- if (is64BitLoadCommand(MachOObj, DRI)) {
+ if (is64BitLoadCommand(MachOObj.get(), DRI)) {
InMemoryStruct<macho::Section64> Sect;
getSection64(DRI, Sect);
Result = Sect->Size;
@@ -529,7 +555,7 @@ error_code MachOObjectFile::getSectionSize(DataRefImpl DRI,
error_code MachOObjectFile::getSectionContents(DataRefImpl DRI,
StringRef &Result) const {
- if (is64BitLoadCommand(MachOObj, DRI)) {
+ if (is64BitLoadCommand(MachOObj.get(), DRI)) {
InMemoryStruct<macho::Section64> Sect;
getSection64(DRI, Sect);
Result = MachOObj->getData(Sect->Offset, Sect->Size);
@@ -543,7 +569,7 @@ error_code MachOObjectFile::getSectionContents(DataRefImpl DRI,
error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI,
uint64_t &Result) const {
- if (is64BitLoadCommand(MachOObj, DRI)) {
+ if (is64BitLoadCommand(MachOObj.get(), DRI)) {
InMemoryStruct<macho::Section64> Sect;
getSection64(DRI, Sect);
Result = uint64_t(1) << Sect->Align;
@@ -557,14 +583,14 @@ error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI,
error_code MachOObjectFile::isSectionText(DataRefImpl DRI,
bool &Result) const {
- if (is64BitLoadCommand(MachOObj, DRI)) {
+ if (is64BitLoadCommand(MachOObj.get(), DRI)) {
InMemoryStruct<macho::Section64> Sect;
getSection64(DRI, Sect);
- Result = !strcmp(Sect->Name, "__text");
+ Result = Sect->Flags & macho::SF_PureInstructions;
} else {
InMemoryStruct<macho::Section> Sect;
getSection(DRI, Sect);
- Result = !strcmp(Sect->Name, "__text");
+ Result = Sect->Flags & macho::SF_PureInstructions;
}
return object_error::success;
}
@@ -664,7 +690,7 @@ relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
}
relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
uint32_t last_reloc;
- if (is64BitLoadCommand(MachOObj, Sec)) {
+ if (is64BitLoadCommand(MachOObj.get(), Sec)) {
InMemoryStruct<macho::Section64> Sect;
getSection64(Sec, Sect);
last_reloc = Sect->NumRelocationTableEntries;
@@ -1050,6 +1076,7 @@ error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
printRelocationTargetName(RENext, fmt);
fmt << "-";
printRelocationTargetName(RE, fmt);
+ break;
}
case macho::RIT_X86_64_TLV:
printRelocationTargetName(RE, fmt);
@@ -1277,14 +1304,17 @@ StringRef MachOObjectFile::getFileFormatName() const {
}
}
+ // Make sure the cpu type has the correct mask.
+ assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64)
+ == llvm::MachO::CPUArchABI64 &&
+ "32-bit object file when we're 64-bit?");
+
switch (MachOObj->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:
- assert((MachOObj->getHeader().CPUType & llvm::MachO::CPUArchABI64) == 1 &&
- "32-bit object file when we're 64-bit?");
return "Mach-O 64-bit unknown";
}
}
OpenPOWER on IntegriCloud