[AIX] support read global symbol of big archive
Reviewers: James Henderson, Fangrui Song Differential Revision: https://reviews.llvm.org/D124865
This commit is contained in:
parent
8aad330eeb
commit
a6316d6da5
|
@ -379,10 +379,10 @@ protected:
|
|||
uint64_t getArchiveMagicLen() const;
|
||||
void setFirstRegular(const Child &C);
|
||||
|
||||
private:
|
||||
StringRef SymbolTable;
|
||||
StringRef StringTable;
|
||||
|
||||
private:
|
||||
StringRef FirstRegularData;
|
||||
uint16_t FirstRegularStartOfFile = -1;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -65,6 +65,10 @@ Symbols:
|
|||
# RUN: llvm-nm --print-armap %t.a | FileCheck %s
|
||||
# RUN: not grep '/SYM64/' %t.a
|
||||
|
||||
# RUN: rm -f %t.a
|
||||
# RUN: llvm-ar rcsU --format=bigarchive %t.a %t.elf-x86-64 %t2.elf-x86-64
|
||||
# RUN: llvm-nm --print-armap %t.a | FileCheck %s
|
||||
|
||||
# CHECK: Archive map
|
||||
# CHECK-NEXT: main in {{.*}}.elf-x86-64
|
||||
# CHECK-NEXT: foo in {{.*}}2.elf-x86-64
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# XFAIL: system-aix
|
||||
## Test the deletion of members and that symbols are removed from the symbol table.
|
||||
|
||||
# RUN: yaml2obj %s -o %t-delete.o --docnum=1
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
## Test malformed global symbal table of big archive.
|
||||
|
||||
# RUN: rm -rf %t && mkdir %t && cd %t
|
||||
# RUN: yaml2obj %s -o t.o
|
||||
# RUN: llvm-ar q t.a t.o
|
||||
# RUN: cp t.a t2.a
|
||||
|
||||
## Truncate the file to end before the global symbol table header ends.
|
||||
# RUN: %python -c "with open('t.a', 'r+b') as input: input.truncate(560)"
|
||||
## Truncate the file to end before the global symbol table ends.
|
||||
# RUN: %python -c "with open('t2.a', 'r+b') as input: input.truncate(656)"
|
||||
|
||||
# RUN: not llvm-ar t t.a 2>&1 | FileCheck -DFILE=t.a %s
|
||||
# RUN: not llvm-ar t t2.a 2>&1 | FileCheck -DFILE=t2.a --check-prefixes=CHECK2 %s
|
||||
|
||||
# CHECK: error: unable to load '[[FILE]]': truncated or malformed archive (global symbol table header at offset 0x20e and size 0x72 goes past the end of file)
|
||||
# CHECK2: error: unable to load '[[FILE]]': truncated or malformed archive (global symbol table content at offset 0x280 and size 0x25 goes past the end of file)
|
||||
|
||||
--- !XCOFF
|
||||
FileHeader:
|
||||
MagicNumber: 0x1DF
|
||||
Sections:
|
||||
- Name: .data
|
||||
Flags: [ STYP_DATA ]
|
||||
Symbols:
|
||||
- Name: export_protected_var
|
||||
Section: .data
|
||||
Type: 0x4000
|
||||
StorageClass: C_EXT
|
||||
AuxEntries:
|
||||
- Type: AUX_CSECT
|
||||
SymbolAlignmentAndType: 0x09
|
||||
StorageMappingClass: XMC_RW
|
Loading…
Reference in New Issue