aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-08-24 11:56:58 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-08-24 11:56:58 +0000
commit0c7761b3f98fee270d73f5b9c440fe15e82af263 (patch)
tree8af4df64a2907bb3c054bd4a595f5aa3e413a25d /lib
parent15af79c8f8ddc3fdefe668cf6a92548b970486e7 (diff)
downloadexternal_llvm-0c7761b3f98fee270d73f5b9c440fe15e82af263.zip
external_llvm-0c7761b3f98fee270d73f5b9c440fe15e82af263.tar.gz
external_llvm-0c7761b3f98fee270d73f5b9c440fe15e82af263.tar.bz2
llvm-mc/Mach-O: Preliminary support for indirect symbols.
- The indirect table itself isn't being filled in yet. - This isn't factored properly and is rather FIXMEd, but at the moment I'm more focused on figuring out what it needs to do. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79910 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/MC/MCAssembler.cpp98
-rw-r--r--lib/MC/MCMachOStreamer.cpp15
2 files changed, 96 insertions, 17 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 9315422..22e0c0d 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -311,12 +311,68 @@ public:
Write32(0); // FIXME: Value
}
+ void BindIndirectSymbols(MCAssembler &Asm) {
+ // This is the point where 'as' creates actual symbols for indirect symbols
+ // (in the following two passes). It would be easier for us to do this
+ // sooner when we see the attribute, but that makes getting the order in the
+ // symbol table much more complicated than it is worth.
+ //
+ // FIXME: Revisit this when the dust settles.
+
+ // FIXME: This should not be needed.
+ DenseMap<MCSymbol*, MCSymbolData *> SymbolMap;
+
+ for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
+ ie = Asm.symbol_end(); it != ie; ++it)
+ SymbolMap[&it->getSymbol()] = it;
+
+ // Bind non lazy symbol pointers first.
+ for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
+ ie = Asm.indirect_symbol_end(); it != ie; ++it) {
+ // FIXME: cast<> support!
+ const MCSectionMachO &Section =
+ static_cast<const MCSectionMachO&>(it->SectionData->getSection());
+
+ unsigned Type =
+ Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE;
+ if (Type != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS)
+ continue;
+
+ MCSymbolData *&Entry = SymbolMap[it->Symbol];
+ if (!Entry)
+ Entry = new MCSymbolData(*it->Symbol, 0, 0, &Asm);
+ }
+
+ // Then lazy symbol pointers and symbol stubs.
+ for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
+ ie = Asm.indirect_symbol_end(); it != ie; ++it) {
+ // FIXME: cast<> support!
+ const MCSectionMachO &Section =
+ static_cast<const MCSectionMachO&>(it->SectionData->getSection());
+
+ unsigned Type =
+ Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE;
+ if (Type != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
+ Type != MCSectionMachO::S_SYMBOL_STUBS)
+ continue;
+
+ MCSymbolData *&Entry = SymbolMap[it->Symbol];
+ if (!Entry) {
+ Entry = new MCSymbolData(*it->Symbol, 0, 0, &Asm);
+
+ // Set the symbol type to undefined lazy, but only on construction.
+ //
+ // FIXME: Do not hardcode.
+ Entry->setFlags(Entry->getFlags() | 0x0001);
+ }
+ }
+ }
+
/// ComputeSymbolTable - Compute the symbol table data
///
/// \param StringTable [out] - The string table data.
/// \param StringIndexMap [out] - Map from symbol names to offsets in the
/// string table.
-
void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
std::vector<MachSymbolData> &LocalSymbolData,
std::vector<MachSymbolData> &ExternalSymbolData,
@@ -414,6 +470,8 @@ public:
void WriteObject(MCAssembler &Asm) {
unsigned NumSections = Asm.size();
+ BindIndirectSymbols(Asm);
+
// Compute symbol table information.
SmallString<256> StringTable;
std::vector<MachSymbolData> LocalSymbolData;
@@ -467,22 +525,32 @@ public:
// Write the symbol table load command, if used.
if (NumSymbols) {
- // The string table is written after all the section data.
- uint64_t SymbolTableOffset = SectionDataStartOffset + SectionDataSize;
- uint64_t StringTableOffset =
- SymbolTableOffset + NumSymbols * Nlist32Size;
- WriteSymtabLoadCommand(SymbolTableOffset, NumSymbols,
- StringTableOffset, StringTable.size());
-
unsigned FirstLocalSymbol = 0;
unsigned NumLocalSymbols = LocalSymbolData.size();
unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
unsigned NumExternalSymbols = ExternalSymbolData.size();
unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
- // FIXME: Get correct symbol indices and counts for indirect symbols.
- unsigned IndirectSymbolOffset = 0;
- unsigned NumIndirectSymbols = 0;
+ unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
+ unsigned NumSymTabSymbols =
+ NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
+ uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
+ uint64_t IndirectSymbolOffset = 0;
+
+ // If used, the indirect symbols are written after the section data.
+ if (NumIndirectSymbols)
+ IndirectSymbolOffset = SectionDataStartOffset + SectionDataSize;
+
+ // The symbol table is written after the indirect symbol data.
+ uint64_t SymbolTableOffset =
+ SectionDataStartOffset + SectionDataSize + IndirectSymbolSize;
+
+ // The string table is written after symbol table.
+ uint64_t StringTableOffset =
+ SymbolTableOffset + NumSymTabSymbols * Nlist32Size;
+ WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
+ StringTableOffset, StringTable.size());
+
WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
FirstExternalSymbol, NumExternalSymbols,
FirstUndefinedSymbol, NumUndefinedSymbols,
@@ -495,9 +563,13 @@ public:
// Write the symbol table data, if used.
if (NumSymbols) {
- // FIXME: Check that offsets match computed ones.
+ // Write the indirect symbol entries.
+ //
+ // FIXME: We need the symbol index map for this.
+ for (unsigned i = 0, e = Asm.indirect_symbol_size(); i != e; ++i)
+ Write32(0);
- // FIXME: Some of these are ordered by name to help the linker.
+ // FIXME: Check that offsets match computed ones.
// Write the symbol table entries.
for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 9d60e3e..f49f6e0 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -165,6 +165,16 @@ void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol,
void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
SymbolAttr Attribute) {
+ // Indirect symbols are handled differently, to match how 'as' handles
+ // them. This makes writing matching .o files easier.
+ if (Attribute == MCStreamer::IndirectSymbol) {
+ IndirectSymbolData ISD;
+ ISD.Symbol = Symbol;
+ ISD.SectionData = CurSectionData;
+ Assembler.getIndirectSymbols().push_back(ISD);
+ return;
+ }
+
// Adding a symbol attribute always introduces the symbol, note that an
// important side effect of calling getSymbolData here is to register the
// symbol with the assembler.
@@ -177,6 +187,7 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
// In the future it might be worth trying to make these operations more well
// defined.
switch (Attribute) {
+ case MCStreamer::IndirectSymbol:
case MCStreamer::Hidden:
case MCStreamer::Internal:
case MCStreamer::Protected:
@@ -195,10 +206,6 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy);
break;
- case MCStreamer::IndirectSymbol:
- llvm_unreachable("FIXME: Not yet implemented!");
- break;
-
// Since .reference sets the no dead strip bit, it is equivalent to
// .no_dead_strip in practice.
case MCStreamer::Reference: