[Object] Fix endianess bug by refactoring Archive::Symbol::getMember.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167893 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Michael J. Spencer 2012-11-14 00:04:13 +00:00
parent e123fd9c59
commit 768a707fdf

View File

@ -265,31 +265,45 @@ error_code Archive::Symbol::getName(StringRef &Result) const {
} }
error_code Archive::Symbol::getMember(child_iterator &Result) const { error_code Archive::Symbol::getMember(child_iterator &Result) const {
const char *buf = Parent->SymbolTable->getBuffer()->getBufferStart(); const char *Buf = Parent->SymbolTable->getBuffer()->getBufferStart();
const char *offsets = buf + 4; const char *Offsets = Buf + 4;
uint32_t offset = 0; uint32_t Offset = 0;
if (Parent->kind() == K_GNU) { if (Parent->kind() == K_GNU) {
offset = *(reinterpret_cast<const support::ubig32_t*>(offsets) Offset = *(reinterpret_cast<const support::ubig32_t*>(Offsets)
+ SymbolIndex); + SymbolIndex);
} else if (Parent->kind() == K_BSD) { } else if (Parent->kind() == K_BSD) {
assert("BSD format is not supported"); assert("BSD format is not supported");
} else { } else {
uint32_t member_count = 0; uint32_t MemberCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
buf += 4 + (member_count * 4); // Skip offsets. // Skip offsets.
const char *indicies = buf + 4; Buf += sizeof(support::ulittle32_t)
uint16_t offsetindex = + (MemberCount * sizeof(support::ulittle32_t));
*(reinterpret_cast<const support::ulittle16_t*>(indicies)
uint32_t SymbolCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
if (SymbolIndex >= SymbolCount)
return object_error::parse_failed;
// Skip SymbolCount to get to the indicies table.
const char *Indicies = Buf + sizeof(support::ulittle32_t);
// Get the index of the offset in the file member offset table for this
// symbol.
uint16_t OffsetIndex =
*(reinterpret_cast<const support::ulittle16_t*>(Indicies)
+ SymbolIndex); + SymbolIndex);
uint32_t *offsetaddr = // Subtract 1 since OffsetIndex is 1 based.
(uint32_t *)(reinterpret_cast<const support::ulittle32_t*>(offsets) --OffsetIndex;
+ (offsetindex - 1));
assert((const char *)offsetaddr < if (OffsetIndex >= MemberCount)
Parent->SymbolTable->getBuffer()->getBufferEnd()); return object_error::parse_failed;
offset = *(offsetaddr);
Offset = *(reinterpret_cast<const support::ulittle32_t*>(Offsets)
+ OffsetIndex);
} }
const char *Loc = Parent->getData().begin() + offset; const char *Loc = Parent->getData().begin() + Offset;
size_t Size = sizeof(ArchiveMemberHeader) + size_t Size = sizeof(ArchiveMemberHeader) +
ToHeader(Loc)->getSize(); ToHeader(Loc)->getSize();
Result = Child(Parent, StringRef(Loc, Size)); Result = Child(Parent, StringRef(Loc, Size));