mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-04 17:58:22 +00:00
Basic support for BSD symbol tables in archives.
This could be optimized and for now we only produce __.SYMDEF and not "__.SYMDEF SORTED". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241814 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8e78dfcf23
commit
a55816b3fc
@ -184,10 +184,8 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
|
||||
ArrayRef<NewArchiveIterator> Members,
|
||||
ArrayRef<MemoryBufferRef> Buffers,
|
||||
std::vector<unsigned> &MemberOffsetRefs) {
|
||||
if (Kind != object::Archive::K_GNU)
|
||||
return 0;
|
||||
|
||||
unsigned StartOffset = 0;
|
||||
unsigned HeaderStartOffset = 0;
|
||||
unsigned BodyStartOffset = 0;
|
||||
SmallString<128> NameBuf;
|
||||
raw_svector_ostream NameOS(NameBuf);
|
||||
LLVMContext Context;
|
||||
@ -200,10 +198,15 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
|
||||
continue; // FIXME: check only for "not an object file" errors.
|
||||
object::SymbolicFile &Obj = *ObjOrErr.get();
|
||||
|
||||
if (!StartOffset) {
|
||||
printGNUSmallMemberHeader(Out, "", sys::TimeValue::now(), 0, 0, 0, 0);
|
||||
StartOffset = Out.tell();
|
||||
print32(Out, Kind, 0);
|
||||
if (!HeaderStartOffset) {
|
||||
HeaderStartOffset = Out.tell();
|
||||
if (Kind == object::Archive::K_GNU)
|
||||
printGNUSmallMemberHeader(Out, "", sys::TimeValue::now(), 0, 0, 0, 0);
|
||||
else
|
||||
printBSDMemberHeader(Out, "__.SYMDEF", sys::TimeValue::now(), 0, 0, 0,
|
||||
0);
|
||||
BodyStartOffset = Out.tell();
|
||||
print32(Out, Kind, 0); // number of entries or bytes
|
||||
}
|
||||
|
||||
for (const object::BasicSymbolRef &S : Obj.symbols()) {
|
||||
@ -214,29 +217,45 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
|
||||
continue;
|
||||
if (Symflags & object::SymbolRef::SF_Undefined)
|
||||
continue;
|
||||
|
||||
unsigned NameOffset = NameOS.tell();
|
||||
if (auto EC = S.printName(NameOS))
|
||||
return EC;
|
||||
NameOS << '\0';
|
||||
MemberOffsetRefs.push_back(MemberNum);
|
||||
print32(Out, Kind, 0);
|
||||
if (Kind == object::Archive::K_BSD)
|
||||
print32(Out, Kind, NameOffset);
|
||||
print32(Out, Kind, 0); // member offset
|
||||
}
|
||||
}
|
||||
Out << NameOS.str();
|
||||
|
||||
if (StartOffset == 0)
|
||||
if (HeaderStartOffset == 0)
|
||||
return 0;
|
||||
|
||||
StringRef StringTable = NameOS.str();
|
||||
if (Kind == object::Archive::K_BSD)
|
||||
print32(Out, Kind, StringTable.size()); // byte count of the string table
|
||||
Out << StringTable;
|
||||
|
||||
if (Out.tell() % 2)
|
||||
Out << '\0';
|
||||
|
||||
// Patch up the size of the symbol table now that we know how big it is.
|
||||
unsigned Pos = Out.tell();
|
||||
Out.seek(StartOffset - 12);
|
||||
printWithSpacePadding(Out, Pos - StartOffset, 10);
|
||||
Out.seek(StartOffset);
|
||||
const unsigned MemberHeaderSize = 60;
|
||||
Out.seek(HeaderStartOffset + 48); // offset of the size field.
|
||||
printWithSpacePadding(Out, Pos - MemberHeaderSize - HeaderStartOffset, 10);
|
||||
|
||||
// Patch up the number of symbols.
|
||||
Out.seek(BodyStartOffset);
|
||||
unsigned NumSyms = MemberOffsetRefs.size();
|
||||
print32(Out, Kind, NumSyms);
|
||||
if (Kind == object::Archive::K_GNU)
|
||||
print32(Out, Kind, NumSyms);
|
||||
else
|
||||
print32(Out, Kind, NumSyms * 8);
|
||||
|
||||
Out.seek(Pos);
|
||||
return StartOffset + 4;
|
||||
return BodyStartOffset + 4;
|
||||
}
|
||||
|
||||
std::pair<StringRef, std::error_code>
|
||||
@ -337,8 +356,11 @@ llvm::writeArchive(StringRef ArcName,
|
||||
|
||||
if (MemberReferenceOffset) {
|
||||
Out.seek(MemberReferenceOffset);
|
||||
for (unsigned MemberNum : MemberOffsetRefs)
|
||||
for (unsigned MemberNum : MemberOffsetRefs) {
|
||||
if (Kind == object::Archive::K_BSD)
|
||||
Out.seek(Out.tell() + 4); // skip over the string offset
|
||||
print32(Out, Kind, MemberOffset[MemberNum]);
|
||||
}
|
||||
}
|
||||
|
||||
Output.keep();
|
||||
|
@ -66,3 +66,24 @@ RUN: llvm-nm -M %p/Inputs/macho-archive-unsorted-x86_64.a | FileCheck %s --check
|
||||
BSD-MachO: Archive map
|
||||
BSD-MachO: _bar in bar.o
|
||||
BSD-MachO: _foo in foo.o
|
||||
|
||||
RUN: rm -f %t.a
|
||||
RUN: llvm-ar --format=bsd rcs %t.a %p/Inputs/trivial-object-test.macho-x86-64 %p/Inputs/trivial-object-test2.macho-x86-64
|
||||
RUN: llvm-nm -M %t.a | FileCheck --check-prefix=MACHO %s
|
||||
|
||||
MACHO: Archive map
|
||||
MACHO-NEXT: _main in trivial-object-test.macho-x86-64
|
||||
MACHO-NEXT: _foo in trivial-object-test2.macho-x86-64
|
||||
MACHO-NEXT: _main in trivial-object-test2.macho-x86-64
|
||||
MACHO-NOT: bar
|
||||
|
||||
MACHO: trivial-object-test.macho-x86-64
|
||||
MACHO-NEXT: 0000000000000028 s L_.str
|
||||
MACHO-NEXT: U _SomeOtherFunction
|
||||
MACHO-NEXT: 0000000000000000 T _main
|
||||
MACHO-NEXT: U _puts
|
||||
|
||||
MACHO: trivial-object-test2.macho-x86-64
|
||||
MACHO-NEXT: 0000000000000000 t _bar
|
||||
MACHO-NEXT: 0000000000000001 T _foo
|
||||
MACHO-NEXT: 0000000000000002 T _main
|
||||
|
Loading…
Reference in New Issue
Block a user