aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Object
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-03-05 23:27:24 -0800
committerStephen Hines <srhines@google.com>2013-03-05 23:27:24 -0800
commit5adb136be579e8fff3734461580cb34d1d2983b8 (patch)
treebff1a422e9c9789df563aaf9a7e91e63e8ec0384 /lib/Object
parent227a4a4ade38716ba9eb3205f48b52910f3b955e (diff)
parentb3201c5cf1e183d840f7c99ff779d57f1549d8e5 (diff)
downloadexternal_llvm-5adb136be579e8fff3734461580cb34d1d2983b8.zip
external_llvm-5adb136be579e8fff3734461580cb34d1d2983b8.tar.gz
external_llvm-5adb136be579e8fff3734461580cb34d1d2983b8.tar.bz2
Merge commit 'b3201c5cf1e183d840f7c99ff779d57f1549d8e5' into merge_20130226
Conflicts: include/llvm/Support/ELF.h lib/Support/DeltaAlgorithm.cpp Change-Id: I24a4fbce62eb39d924efee3c687b55e1e17b30cd
Diffstat (limited to 'lib/Object')
-rw-r--r--lib/Object/Archive.cpp122
-rw-r--r--lib/Object/COFFObjectFile.cpp2
-rw-r--r--lib/Object/ELFObjectFile.cpp36
-rw-r--r--lib/Object/MachOObject.cpp14
-rw-r--r--lib/Object/MachOObjectFile.cpp3
-rw-r--r--lib/Object/ObjectFile.cpp4
6 files changed, 65 insertions, 116 deletions
diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp
index dafcb72..0e13d05 100644
--- a/lib/Object/Archive.cpp
+++ b/lib/Object/Archive.cpp
@@ -14,7 +14,6 @@
#include "llvm/Object/Archive.h"
#include "llvm/ADT/APInt.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
using namespace llvm;
@@ -22,44 +21,6 @@ using namespace object;
static const char *Magic = "!<arch>\n";
-namespace {
-struct ArchiveMemberHeader {
- char Name[16];
- char LastModified[12];
- char UID[6];
- char GID[6];
- char AccessMode[8];
- char Size[10]; ///< Size of data, not including header or padding.
- char Terminator[2];
-
- ///! Get the name without looking up long names.
- StringRef getName() const {
- char EndCond;
- if (Name[0] == '/' || Name[0] == '#')
- EndCond = ' ';
- else
- EndCond = '/';
- StringRef::size_type end = StringRef(Name, sizeof(Name)).find(EndCond);
- if (end == StringRef::npos)
- end = sizeof(Name);
- assert(end <= sizeof(Name) && end > 0);
- // Don't include the EndCond if there is one.
- return StringRef(Name, end);
- }
-
- uint64_t getSize() const {
- APInt ret;
- StringRef(Size, sizeof(Size)).getAsInteger(10, ret);
- return ret.getZExtValue();
- }
-};
-}
-
-static const ArchiveMemberHeader *ToHeader(const char *base) {
- return reinterpret_cast<const ArchiveMemberHeader *>(base);
-}
-
-
static bool isInternalMember(const ArchiveMemberHeader &amh) {
static const char *const internals[] = {
"/",
@@ -77,25 +38,6 @@ static bool isInternalMember(const ArchiveMemberHeader &amh) {
void Archive::anchor() { }
-Archive::Child Archive::Child::getNext() const {
- size_t SpaceToSkip = sizeof(ArchiveMemberHeader) +
- ToHeader(Data.data())->getSize();
- // If it's odd, add 1 to make it even.
- if (SpaceToSkip & 1)
- ++SpaceToSkip;
-
- const char *NextLoc = Data.data() + SpaceToSkip;
-
- // Check to see if this is past the end of the archive.
- if (NextLoc >= Parent->Data->getBufferEnd())
- return Child(Parent, StringRef(0, 0));
-
- size_t NextSize = sizeof(ArchiveMemberHeader) +
- ToHeader(NextLoc)->getSize();
-
- return Child(Parent, StringRef(NextLoc, NextSize));
-}
-
error_code Archive::Child::getName(StringRef &Result) const {
StringRef name = ToHeader(Data.data())->getName();
// Check if it's a special name.
@@ -110,11 +52,12 @@ error_code Archive::Child::getName(StringRef &Result) const {
}
// It's a long name.
// Get the offset.
- APInt offset;
- name.substr(1).getAsInteger(10, offset);
+ std::size_t offset;
+ if (name.substr(1).rtrim(" ").getAsInteger(10, offset))
+ llvm_unreachable("Long name offset is not an integer");
const char *addr = Parent->StringTable->Data.begin()
+ sizeof(ArchiveMemberHeader)
- + offset.getZExtValue();
+ + offset;
// Verify it.
if (Parent->StringTable == Parent->end_children()
|| addr < (Parent->StringTable->Data.begin()
@@ -133,9 +76,10 @@ error_code Archive::Child::getName(StringRef &Result) const {
}
return object_error::success;
} else if (name.startswith("#1/")) {
- APInt name_size;
- name.substr(3).getAsInteger(10, name_size);
- Result = Data.substr(0, name_size.getZExtValue());
+ uint64_t name_size;
+ if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
+ llvm_unreachable("Long name length is not an ingeter");
+ Result = Data.substr(sizeof(ArchiveMemberHeader), name_size);
return object_error::success;
}
// It's a simple name.
@@ -146,36 +90,12 @@ error_code Archive::Child::getName(StringRef &Result) const {
return object_error::success;
}
-uint64_t Archive::Child::getSize() const {
- uint64_t size = ToHeader(Data.data())->getSize();
- // Don't include attached name.
- StringRef name = ToHeader(Data.data())->getName();
- if (name.startswith("#1/")) {
- APInt name_size;
- name.substr(3).getAsInteger(10, name_size);
- size -= name_size.getZExtValue();
- }
- return size;
-}
-
-MemoryBuffer *Archive::Child::getBuffer() const {
- StringRef name;
- if (getName(name)) return NULL;
- int size = sizeof(ArchiveMemberHeader);
- if (name.startswith("#1/")) {
- APInt name_size;
- name.substr(3).getAsInteger(10, name_size);
- size += name_size.getZExtValue();
- }
- return MemoryBuffer::getMemBuffer(Data.substr(size, getSize()),
- name,
- false);
-}
-
error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const {
OwningPtr<Binary> ret;
- if (error_code ec =
- createBinary(getBuffer(), ret))
+ OwningPtr<MemoryBuffer> Buff;
+ if (error_code ec = getMemoryBuffer(Buff))
+ return ec;
+ if (error_code ec = createBinary(Buff.take(), ret))
return ec;
Result.swap(ret);
return object_error::success;
@@ -218,6 +138,10 @@ Archive::Archive(MemoryBuffer *source, error_code &ec)
SymbolTable = i;
StringTable = e;
if (i != e) ++i;
+ if (i == e) {
+ ec = object_error::parse_failed;
+ return;
+ }
if ((ec = i->getName(name)))
return;
if (name[0] != '/') {
@@ -260,13 +184,12 @@ Archive::child_iterator Archive::end_children() const {
}
error_code Archive::Symbol::getName(StringRef &Result) const {
- Result =
- StringRef(Parent->SymbolTable->getBuffer()->getBufferStart() + StringIndex);
+ Result = StringRef(Parent->SymbolTable->getBuffer().begin() + StringIndex);
return object_error::success;
}
error_code Archive::Symbol::getMember(child_iterator &Result) const {
- const char *Buf = Parent->SymbolTable->getBuffer()->getBufferStart();
+ const char *Buf = Parent->SymbolTable->getBuffer().begin();
const char *Offsets = Buf + 4;
uint32_t Offset = 0;
if (Parent->kind() == K_GNU) {
@@ -316,13 +239,13 @@ Archive::Symbol Archive::Symbol::getNext() const {
Symbol t(*this);
// Go to one past next null.
t.StringIndex =
- Parent->SymbolTable->getBuffer()->getBuffer().find('\0', t.StringIndex) + 1;
+ Parent->SymbolTable->getBuffer().find('\0', t.StringIndex) + 1;
++t.SymbolIndex;
return t;
}
Archive::symbol_iterator Archive::begin_symbols() const {
- const char *buf = SymbolTable->getBuffer()->getBufferStart();
+ const char *buf = SymbolTable->getBuffer().begin();
if (kind() == K_GNU) {
uint32_t symbol_count = 0;
symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
@@ -337,13 +260,12 @@ Archive::symbol_iterator Archive::begin_symbols() const {
symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
buf += 4 + (symbol_count * 2); // Skip indices.
}
- uint32_t string_start_offset =
- buf - SymbolTable->getBuffer()->getBufferStart();
+ uint32_t string_start_offset = buf - SymbolTable->getBuffer().begin();
return symbol_iterator(Symbol(this, 0, string_start_offset));
}
Archive::symbol_iterator Archive::end_symbols() const {
- const char *buf = SymbolTable->getBuffer()->getBufferStart();
+ const char *buf = SymbolTable->getBuffer().begin();
uint32_t symbol_count = 0;
if (kind() == K_GNU) {
symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp
index b60a2da..b0b84fc 100644
--- a/lib/Object/COFFObjectFile.cpp
+++ b/lib/Object/COFFObjectFile.cpp
@@ -269,7 +269,7 @@ error_code COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb,
}
if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
- ret = ::toupper(ret);
+ ret = ::toupper(static_cast<unsigned char>(ret));
Result = ret;
return object_error::success;
diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp
index 8d5ac63..62626d7 100644
--- a/lib/Object/ELFObjectFile.cpp
+++ b/lib/Object/ELFObjectFile.cpp
@@ -29,31 +29,43 @@ ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
1ULL << CountTrailingZeros_64(uintptr_t(Object->getBufferStart()));
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
+#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
- return new ELFObjectFile<support::little, 4, false>(Object, ec);
- else if (MaxAlignment >= 2)
- return new ELFObjectFile<support::little, 2, false>(Object, ec);
+ return new ELFObjectFile<ELFType<support::little, 4, false> >(Object, ec);
+ else
+#endif
+ if (MaxAlignment >= 2)
+ return new ELFObjectFile<ELFType<support::little, 2, false> >(Object, ec);
else
llvm_unreachable("Invalid alignment for ELF file!");
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
+#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
- return new ELFObjectFile<support::big, 4, false>(Object, ec);
- else if (MaxAlignment >= 2)
- return new ELFObjectFile<support::big, 2, false>(Object, ec);
+ return new ELFObjectFile<ELFType<support::big, 4, false> >(Object, ec);
+ else
+#endif
+ if (MaxAlignment >= 2)
+ return new ELFObjectFile<ELFType<support::big, 2, false> >(Object, ec);
else
llvm_unreachable("Invalid alignment for ELF file!");
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
+#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
- return new ELFObjectFile<support::big, 8, true>(Object, ec);
- else if (MaxAlignment >= 2)
- return new ELFObjectFile<support::big, 2, true>(Object, ec);
+ return new ELFObjectFile<ELFType<support::big, 8, true> >(Object, ec);
+ else
+#endif
+ if (MaxAlignment >= 2)
+ return new ELFObjectFile<ELFType<support::big, 2, true> >(Object, ec);
else
llvm_unreachable("Invalid alignment for ELF file!");
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
+#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
- return new ELFObjectFile<support::little, 8, true>(Object, ec);
- else if (MaxAlignment >= 2)
- return new ELFObjectFile<support::little, 2, true>(Object, ec);
+ return new ELFObjectFile<ELFType<support::little, 8, true> >(Object, ec);
+ else
+#endif
+ if (MaxAlignment >= 2)
+ return new ELFObjectFile<ELFType<support::little, 2, true> >(Object, ec);
else
llvm_unreachable("Invalid alignment for ELF file!");
}
diff --git a/lib/Object/MachOObject.cpp b/lib/Object/MachOObject.cpp
index a64db1c..c9c341a 100644
--- a/lib/Object/MachOObject.cpp
+++ b/lib/Object/MachOObject.cpp
@@ -44,7 +44,8 @@ static void ReadInMemoryStruct(const MachOObject &MOO,
}
// Check whether we can return a direct pointer.
- struct_type *Ptr = (struct_type *) (Buffer.data() + Base);
+ struct_type *Ptr = reinterpret_cast<struct_type *>(
+ const_cast<char *>(Buffer.data() + Base));
if (!MOO.isSwappedEndian()) {
Res = Ptr;
return;
@@ -258,6 +259,17 @@ void MachOObject::ReadLinkeditDataLoadCommand(const LoadCommandInfo &LCI,
}
template<>
+void SwapStruct(macho::LinkerOptionsLoadCommand &Value) {
+ SwapValue(Value.Type);
+ SwapValue(Value.Size);
+ SwapValue(Value.Count);
+}
+void MachOObject::ReadLinkerOptionsLoadCommand(const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const {
+ ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
+}
+
+template<>
void SwapStruct(macho::IndirectSymbolTableEntry &Value) {
SwapValue(Value.Index);
}
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp
index 0ad8893..eb1690e 100644
--- a/lib/Object/MachOObjectFile.cpp
+++ b/lib/Object/MachOObjectFile.cpp
@@ -273,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;
}
@@ -1076,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);
diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp
index b14df9a..860c87b 100644
--- a/lib/Object/ObjectFile.cpp
+++ b/lib/Object/ObjectFile.cpp
@@ -33,6 +33,8 @@ ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) {
sys::LLVMFileType type = sys::IdentifyFileType(Object->getBufferStart(),
static_cast<unsigned>(Object->getBufferSize()));
switch (type) {
+ case sys::Unknown_FileType:
+ return 0;
case sys::ELF_Relocatable_FileType:
case sys::ELF_Executable_FileType:
case sys::ELF_SharedObject_FileType:
@@ -52,7 +54,7 @@ ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) {
case sys::COFF_FileType:
return createCOFFObjectFile(Object);
default:
- llvm_unreachable("Unknown Object File Type");
+ llvm_unreachable("Unexpected Object File Type");
}
}