diff options
author | Stephen Hines <srhines@google.com> | 2013-03-05 23:27:24 -0800 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2013-03-05 23:27:24 -0800 |
commit | 5adb136be579e8fff3734461580cb34d1d2983b8 (patch) | |
tree | bff1a422e9c9789df563aaf9a7e91e63e8ec0384 /lib/Object | |
parent | 227a4a4ade38716ba9eb3205f48b52910f3b955e (diff) | |
parent | b3201c5cf1e183d840f7c99ff779d57f1549d8e5 (diff) | |
download | external_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.cpp | 122 | ||||
-rw-r--r-- | lib/Object/COFFObjectFile.cpp | 2 | ||||
-rw-r--r-- | lib/Object/ELFObjectFile.cpp | 36 | ||||
-rw-r--r-- | lib/Object/MachOObject.cpp | 14 | ||||
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 3 | ||||
-rw-r--r-- | lib/Object/ObjectFile.cpp | 4 |
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"); } } |