diff options
Diffstat (limited to 'llvm/lib/Object')
| -rw-r--r-- | llvm/lib/Object/Archive.cpp | 61 | ||||
| -rw-r--r-- | llvm/lib/Object/Decompressor.cpp | 39 | ||||
| -rw-r--r-- | llvm/lib/Object/WasmObjectFile.cpp | 2 |
3 files changed, 60 insertions, 42 deletions
diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp index ad03f9cae9f8..1dffe007b9a9 100644 --- a/llvm/lib/Object/Archive.cpp +++ b/llvm/lib/Object/Archive.cpp @@ -965,14 +965,15 @@ StringRef Archive::Symbol::getName() const { Expected<Archive::Child> Archive::Symbol::getMember() const { const char *Buf = Parent->getSymbolTable().begin(); const char *Offsets = Buf; - if (Parent->kind() == K_GNU64 || Parent->kind() == K_DARWIN64) + if (Parent->kind() == K_GNU64 || Parent->kind() == K_DARWIN64 || + Parent->kind() == K_AIXBIG) Offsets += sizeof(uint64_t); else Offsets += sizeof(uint32_t); uint64_t Offset = 0; if (Parent->kind() == K_GNU) { Offset = read32be(Offsets + SymbolIndex * 4); - } else if (Parent->kind() == K_GNU64) { + } else if (Parent->kind() == K_GNU64 || Parent->kind() == K_AIXBIG) { Offset = read64be(Offsets + SymbolIndex * 8); } else if (Parent->kind() == K_BSD) { // The SymbolIndex is an index into the ranlib structs that start at @@ -1105,6 +1106,8 @@ Archive::symbol_iterator Archive::symbol_begin() const { // Skip the byte count of the string table. buf += sizeof(uint64_t); buf += ran_strx; + } else if (kind() == K_AIXBIG) { + buf = getStringTable().begin(); } else { uint32_t member_count = 0; uint32_t symbol_count = 0; @@ -1127,7 +1130,7 @@ uint32_t Archive::getNumberOfSymbols() const { const char *buf = getSymbolTable().begin(); if (kind() == K_GNU) return read32be(buf); - if (kind() == K_GNU64) + if (kind() == K_GNU64 || kind() == K_AIXBIG) return read64be(buf); if (kind() == K_BSD) return read32le(buf) / 8; @@ -1180,6 +1183,58 @@ BigArchive::BigArchive(MemoryBufferRef Source, Error &Err) Err = malformedError("malformed AIX big archive: last member offset \"" + RawOffset + "\" is not a number"); + // Calculate the global symbol table. + uint64_t GlobSymOffset = 0; + RawOffset = getFieldRawString(ArFixLenHdr->GlobSymOffset); + if (RawOffset.getAsInteger(10, GlobSymOffset)) + // TODO: add test case. + Err = malformedError( + "malformed AIX big archive: global symbol table offset \"" + RawOffset + + "\" is not a number"); + + if (Err) + return; + + if (GlobSymOffset > 0) { + uint64_t BufferSize = Data.getBufferSize(); + uint64_t GlobalSymTblContentOffset = + GlobSymOffset + sizeof(BigArMemHdrType); + if (GlobalSymTblContentOffset > BufferSize) { + Err = malformedError("global symbol table header at offset 0x" + + Twine::utohexstr(GlobSymOffset) + " and size 0x" + + Twine::utohexstr(sizeof(BigArMemHdrType)) + + " goes past the end of file"); + return; + } + + const char *GlobSymTblLoc = Data.getBufferStart() + GlobSymOffset; + const BigArMemHdrType *GlobalSymHdr = + reinterpret_cast<const BigArMemHdrType *>(GlobSymTblLoc); + RawOffset = getFieldRawString(GlobalSymHdr->Size); + uint64_t Size; + if (RawOffset.getAsInteger(10, Size)) { + // TODO: add test case. + Err = malformedError( + "malformed AIX big archive: global symbol table size \"" + RawOffset + + "\" is not a number"); + return; + } + if (GlobalSymTblContentOffset + Size > BufferSize) { + Err = malformedError("global symbol table content at offset 0x" + + Twine::utohexstr(GlobalSymTblContentOffset) + + " and size 0x" + Twine::utohexstr(Size) + + " goes past the end of file"); + return; + } + SymbolTable = StringRef(GlobSymTblLoc + sizeof(BigArMemHdrType), Size); + unsigned SymNum = getNumberOfSymbols(); + unsigned SymOffsetsSize = 8 * (SymNum + 1); + uint64_t SymbolTableStringSize = Size - SymOffsetsSize; + StringTable = + StringRef(GlobSymTblLoc + sizeof(BigArMemHdrType) + SymOffsetsSize, + SymbolTableStringSize); + } + child_iterator I = child_begin(Err, false); if (Err) return; diff --git a/llvm/lib/Object/Decompressor.cpp b/llvm/lib/Object/Decompressor.cpp index a6a28a0589ac..3842ec92ccfc 100644 --- a/llvm/lib/Object/Decompressor.cpp +++ b/llvm/lib/Object/Decompressor.cpp @@ -23,9 +23,7 @@ Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data, return createError("zlib is not available"); Decompressor D(Data); - Error Err = isGnuStyle(Name) ? D.consumeCompressedGnuHeader() - : D.consumeCompressedZLibHeader(Is64Bit, IsLE); - if (Err) + if (Error Err = D.consumeCompressedZLibHeader(Is64Bit, IsLE)) return std::move(Err); return D; } @@ -33,21 +31,6 @@ Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data, Decompressor::Decompressor(StringRef Data) : SectionData(Data), DecompressedSize(0) {} -Error Decompressor::consumeCompressedGnuHeader() { - if (!SectionData.startswith("ZLIB")) - return createError("corrupted compressed section header"); - - SectionData = SectionData.substr(4); - - // Consume uncompressed section size (big-endian 8 bytes). - if (SectionData.size() < 8) - return createError("corrupted uncompressed section size"); - DecompressedSize = read64be(SectionData.data()); - SectionData = SectionData.substr(8); - - return Error::success(); -} - Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian) { using namespace ELF; @@ -72,26 +55,6 @@ Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit, return Error::success(); } -bool Decompressor::isGnuStyle(StringRef Name) { - return Name.startswith(".zdebug"); -} - -bool Decompressor::isCompressed(const object::SectionRef &Section) { - if (Section.isCompressed()) - return true; - - Expected<StringRef> SecNameOrErr = Section.getName(); - if (SecNameOrErr) - return isGnuStyle(*SecNameOrErr); - - consumeError(SecNameOrErr.takeError()); - return false; -} - -bool Decompressor::isCompressedELFSection(uint64_t Flags, StringRef Name) { - return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name); -} - Error Decompressor::decompress(MutableArrayRef<uint8_t> Buffer) { size_t Size = Buffer.size(); return compression::zlib::uncompress(arrayRefFromStringRef(SectionData), diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index ce816b097691..d00359c6deef 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -204,7 +204,7 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr, if (Expr.Extended) { Ctx.Ptr = Start; - while (1) { + while (true) { uint8_t Opcode = readOpcode(Ctx); switch (Opcode) { case wasm::WASM_OPCODE_I32_CONST: |
