[llvm-commits] [llvm] r80059 - in /llvm/trunk: lib/MC/MCAssembler.cpp lib/MC/MCMachOStreamer.cpp test/MC/MachO/symbol-indirect.s

Daniel Dunbar daniel at zuster.org
Tue Aug 25 17:18:21 PDT 2009


Author: ddunbar
Date: Tue Aug 25 19:18:21 2009
New Revision: 80059

URL: http://llvm.org/viewvc/llvm-project?rev=80059&view=rev
Log:
llvm-mc: Improve indirect symbol support (add the indirect index table).

Added:
    llvm/trunk/test/MC/MachO/symbol-indirect.s
Modified:
    llvm/trunk/lib/MC/MCAssembler.cpp
    llvm/trunk/lib/MC/MCMachOStreamer.cpp

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=80059&r1=80058&r2=80059&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Tue Aug 25 19:18:21 2009
@@ -70,6 +70,13 @@
     STF_PrivateExtern  = 0x10
   };
 
+  /// IndirectSymbolFlags - Flags for encoding special values in the indirect
+  /// symbol entry.
+  enum IndirectSymbolFlags {
+    ISF_Local    = 0x80000000,
+    ISF_Absolute = 0x40000000
+  };
+
   /// MachSymbolData - Helper struct for containing some precomputed information
   /// on symbols.
   struct MachSymbolData {
@@ -315,7 +322,8 @@
     Write32(0); // FIXME: Value
   }
 
-  void BindIndirectSymbols(MCAssembler &Asm) {
+  void BindIndirectSymbols(MCAssembler &Asm,
+                           DenseMap<MCSymbol*, MCSymbolData*> &SymbolMap) {
     // 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
@@ -323,13 +331,6 @@
     //
     // 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) {
@@ -474,7 +475,16 @@
   void WriteObject(MCAssembler &Asm) {
     unsigned NumSections = Asm.size();
 
-    BindIndirectSymbols(Asm);
+    // Compute the symbol -> symbol data map.
+    //
+    // FIXME: This should not be here.
+    DenseMap<MCSymbol*, MCSymbolData *> SymbolMap;
+    for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
+           ie = Asm.symbol_end(); it != ie; ++it)
+      SymbolMap[&it->getSymbol()] = it;
+
+    // Create symbol data for any indirect symbols.
+    BindIndirectSymbols(Asm, SymbolMap);
 
     // Compute symbol table information.
     SmallString<256> StringTable;
@@ -567,11 +577,47 @@
 
     // Write the symbol table data, if used.
     if (NumSymbols) {
+      // FIXME: We shouldn't need this index table.
+      DenseMap<MCSymbol*, unsigned> SymbolIndexMap;
+      for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
+        MCSymbol &Symbol = LocalSymbolData[i].SymbolData->getSymbol();
+        SymbolIndexMap.insert(std::make_pair(&Symbol, SymbolIndexMap.size()));
+      }
+      for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
+        MCSymbol &Symbol = ExternalSymbolData[i].SymbolData->getSymbol();
+        SymbolIndexMap.insert(std::make_pair(&Symbol, SymbolIndexMap.size()));
+      }
+      for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
+        MCSymbol &Symbol = UndefinedSymbolData[i].SymbolData->getSymbol();
+        SymbolIndexMap.insert(std::make_pair(&Symbol, SymbolIndexMap.size()));
+      }
+
       // 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);
+      for (MCAssembler::indirect_symbol_iterator
+             it = Asm.indirect_symbol_begin(),
+             ie = Asm.indirect_symbol_end(); it != ie; ++it) {
+        // Indirect symbols in the non lazy symbol pointer section have some
+        // special handling.
+        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) {
+          // If this symbol is defined and internal, mark it as such.
+          if (it->Symbol->isDefined() &&
+              !SymbolMap.lookup(it->Symbol)->isExternal()) {
+            uint32_t Flags = ISF_Local;
+            if (it->Symbol->isAbsolute())
+              Flags |= ISF_Absolute;
+            Write32(Flags);
+            continue;
+          }
+        }
+
+        Write32(SymbolIndexMap[it->Symbol]);
+      }
 
       // FIXME: Check that offsets match computed ones.
 

Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=80059&r1=80058&r2=80059&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Tue Aug 25 19:18:21 2009
@@ -168,6 +168,8 @@
   // Indirect symbols are handled differently, to match how 'as' handles
   // them. This makes writing matching .o files easier.
   if (Attribute == MCStreamer::IndirectSymbol) {
+    // Note that we intentionally cannot use the symbol data here; this is
+    // important for matching the string table that 'as' generates.
     IndirectSymbolData ISD;
     ISD.Symbol = Symbol;
     ISD.SectionData = CurSectionData;

Added: llvm/trunk/test/MC/MachO/symbol-indirect.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/symbol-indirect.s?rev=80059&view=auto

==============================================================================
--- llvm/trunk/test/MC/MachO/symbol-indirect.s (added)
+++ llvm/trunk/test/MC/MachO/symbol-indirect.s Tue Aug 25 19:18:21 2009
@@ -0,0 +1,273 @@
+// RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | macho-dump | FileCheck %s
+
+// FIXME: We are missing a lot of diagnostics on this kind of stuff which the
+// assembler has.
+        
+        .lazy_symbol_pointer
+        .indirect_symbol sym_lsp_B
+        .long 0
+        
+        .globl sym_lsp_A
+        .indirect_symbol sym_lsp_A
+        .long 0
+        
+sym_lsp_C:      
+        .indirect_symbol sym_lsp_C
+        .long 0
+
+// FIXME: Enable this test once missing llvm-mc support is in place.
+.if 0
+        .indirect_symbol sym_lsp_D
+        .long sym_lsp_D
+.endif
+
+        .indirect_symbol sym_lsp_E
+        .long 0xFA
+
+// FIXME: Enable this test once missing llvm-mc support is in place.
+.if 0
+sym_lsp_F = 10
+        .indirect_symbol sym_lsp_F
+        .long 0
+.endif
+
+        .globl sym_lsp_G
+sym_lsp_G:
+        .indirect_symbol sym_lsp_G
+        .long 0
+        
+        .non_lazy_symbol_pointer
+        .indirect_symbol sym_nlp_B
+        .long 0
+
+        .globl sym_nlp_A
+        .indirect_symbol sym_nlp_A
+        .long 0
+
+sym_nlp_C:      
+        .indirect_symbol sym_nlp_C
+        .long 0
+
+// FIXME: Enable this test once missing llvm-mc support is in place.
+.if 0
+        .indirect_symbol sym_nlp_D
+        .long sym_nlp_D
+.endif
+
+        .indirect_symbol sym_nlp_E
+        .long 0xAF
+
+// FIXME: Enable this test once missing llvm-mc support is in place.
+.if 0
+sym_nlp_F = 10
+        .indirect_symbol sym_nlp_F
+        .long 0
+.endif
+
+        .globl sym_nlp_G
+sym_nlp_G:
+        .indirect_symbol sym_nlp_G
+        .long 0
+
+// CHECK: ('cputype', 7)
+// CHECK: ('cpusubtype', 3)
+// CHECK: ('filetype', 1)
+// CHECK: ('num_load_commands', 1)
+// CHECK: ('load_commands_size', 364)
+// CHECK: ('flag', 0)
+// CHECK: ('load_commands', [
+// CHECK:   # Load Command 0
+// CHECK:  (('command', 1)
+// CHECK:   ('size', 260)
+// CHECK:   ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+// CHECK:   ('vm_addr', 0)
+// CHECK:   ('vm_size', 40)
+// CHECK:   ('file_offset', 392)
+// CHECK:   ('file_size', 40)
+// CHECK:   ('maxprot', 7)
+// CHECK:   ('initprot', 7)
+// CHECK:   ('num_sections', 3)
+// CHECK:   ('flags', 0)
+// CHECK:   ('sections', [
+// CHECK:     # Section 0
+// CHECK:    (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+// CHECK:     ('address', 0)
+// CHECK:     ('size', 0)
+// CHECK:     ('offset', 392)
+// CHECK:     ('alignment', 0)
+// CHECK:     ('reloc_offset', 0)
+// CHECK:     ('num_reloc', 0)
+// CHECK:     ('flags', 0x80000000)
+// CHECK:     ('reserved1', 0)
+// CHECK:     ('reserved2', 0)
+// CHECK:    ),
+// CHECK:     # Section 1
+// CHECK:    (('section_name', '__la_symbol_ptr\x00')
+// CHECK:     ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+// CHECK:     ('address', 0)
+// CHECK:     ('size', 20)
+// CHECK:     ('offset', 392)
+// CHECK:     ('alignment', 2)
+// CHECK:     ('reloc_offset', 0)
+// CHECK:     ('num_reloc', 0)
+// CHECK:     ('flags', 0x7)
+// CHECK:     ('reserved1', 0)
+// CHECK:     ('reserved2', 0)
+// CHECK:    ),
+// CHECK:     # Section 2
+// CHECK:    (('section_name', '__nl_symbol_ptr\x00')
+// CHECK:     ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
+        // FIXME: Enable this when fixed!
+// CHECX:     ('address', 20)
+// CHECK:     ('size', 20)
+// CHECK:     ('offset', 412)
+// CHECK:     ('alignment', 2)
+// CHECK:     ('reloc_offset', 0)
+// CHECK:     ('num_reloc', 0)
+// CHECK:     ('flags', 0x6)
+        // FIXME: Enable this when fixed!
+// CHECX:     ('reserved1', 5)
+// CHECK:     ('reserved2', 0)
+// CHECK:    ),
+// CHECK:   ])
+// CHECK:  ),
+// CHECK:   # Load Command 1
+// CHECK:  (('command', 2)
+// CHECK:   ('size', 24)
+// CHECK:   ('symoff', 472)
+// CHECK:   ('nsyms', 10)
+// CHECK:   ('stroff', 592)
+// CHECK:   ('strsize', 104)
+// CHECK:   ('_string_data', '\x00sym_lsp_A\x00sym_lsp_G\x00sym_nlp_A\x00sym_nlp_G\x00sym_nlp_B\x00sym_nlp_E\x00sym_lsp_B\x00sym_lsp_E\x00sym_lsp_C\x00sym_nlp_C\x00\x00\x00\x00')
+// CHECK:   ('_symbols', [
+// CHECK:     # Symbol 0
+// CHECK:    (('n_strx', 81)
+// CHECK:     ('n_type', 0xe)
+// CHECK:     ('n_sect', 2)
+// CHECK:     ('n_desc', 0)
+        // FIXME: Enable this when fixed!
+// CHECX:     ('n_value', 8)
+// CHECK:     ('_string', 'sym_lsp_C')
+// CHECK:    ),
+// CHECK:     # Symbol 1
+// CHECK:    (('n_strx', 91)
+// CHECK:     ('n_type', 0xe)
+// CHECK:     ('n_sect', 3)
+// CHECK:     ('n_desc', 0)
+        // FIXME: Enable this when fixed!
+// CHECX:     ('n_value', 28)
+// CHECK:     ('_string', 'sym_nlp_C')
+// CHECK:    ),
+// CHECK:     # Symbol 2
+// CHECK:    (('n_strx', 11)
+// CHECK:     ('n_type', 0xf)
+// CHECK:     ('n_sect', 2)
+// CHECK:     ('n_desc', 0)
+        // FIXME: Enable this when fixed!
+// CHECX:     ('n_value', 16)
+// CHECK:     ('_string', 'sym_lsp_G')
+// CHECK:    ),
+// CHECK:     # Symbol 3
+// CHECK:    (('n_strx', 31)
+// CHECK:     ('n_type', 0xf)
+// CHECK:     ('n_sect', 3)
+// CHECK:     ('n_desc', 0)
+        // FIXME: Enable this when fixed!
+// CHECX:     ('n_value', 36)
+// CHECK:     ('_string', 'sym_nlp_G')
+// CHECK:    ),
+// CHECK:     # Symbol 4
+// CHECK:    (('n_strx', 1)
+// CHECK:     ('n_type', 0x1)
+// CHECK:     ('n_sect', 0)
+// CHECK:     ('n_desc', 0)
+// CHECK:     ('n_value', 0)
+// CHECK:     ('_string', 'sym_lsp_A')
+// CHECK:    ),
+// CHECK:     # Symbol 5
+// CHECK:    (('n_strx', 61)
+// CHECK:     ('n_type', 0x1)
+// CHECK:     ('n_sect', 0)
+// CHECK:     ('n_desc', 1)
+// CHECK:     ('n_value', 0)
+// CHECK:     ('_string', 'sym_lsp_B')
+// CHECK:    ),
+// CHECK:     # Symbol 6
+// CHECK:    (('n_strx', 71)
+// CHECK:     ('n_type', 0x1)
+// CHECK:     ('n_sect', 0)
+// CHECK:     ('n_desc', 1)
+// CHECK:     ('n_value', 0)
+// CHECK:     ('_string', 'sym_lsp_E')
+// CHECK:    ),
+// CHECK:     # Symbol 7
+// CHECK:    (('n_strx', 21)
+// CHECK:     ('n_type', 0x1)
+// CHECK:     ('n_sect', 0)
+// CHECK:     ('n_desc', 0)
+// CHECK:     ('n_value', 0)
+// CHECK:     ('_string', 'sym_nlp_A')
+// CHECK:    ),
+// CHECK:     # Symbol 8
+// CHECK:    (('n_strx', 41)
+// CHECK:     ('n_type', 0x1)
+// CHECK:     ('n_sect', 0)
+// CHECK:     ('n_desc', 0)
+// CHECK:     ('n_value', 0)
+// CHECK:     ('_string', 'sym_nlp_B')
+// CHECK:    ),
+// CHECK:     # Symbol 9
+// CHECK:    (('n_strx', 51)
+// CHECK:     ('n_type', 0x1)
+// CHECK:     ('n_sect', 0)
+// CHECK:     ('n_desc', 0)
+// CHECK:     ('n_value', 0)
+// CHECK:     ('_string', 'sym_nlp_E')
+// CHECK:    ),
+// CHECK:   ])
+// CHECK:  ),
+// CHECK:   # Load Command 2
+// CHECK:  (('command', 11)
+// CHECK:   ('size', 80)
+// CHECK:   ('ilocalsym', 0)
+// CHECK:   ('nlocalsym', 2)
+// CHECK:   ('iextdefsym', 2)
+// CHECK:   ('nextdefsym', 2)
+// CHECK:   ('iundefsym', 4)
+// CHECK:   ('nundefsym', 6)
+// CHECK:   ('tocoff', 0)
+// CHECK:   ('ntoc', 0)
+// CHECK:   ('modtaboff', 0)
+// CHECK:   ('nmodtab', 0)
+// CHECK:   ('extrefsymoff', 0)
+// CHECK:   ('nextrefsyms', 0)
+// CHECK:   ('indirectsymoff', 432)
+// CHECK:   ('nindirectsyms', 10)
+// CHECK:   ('extreloff', 0)
+// CHECK:   ('nextrel', 0)
+// CHECK:   ('locreloff', 0)
+// CHECK:   ('nlocrel', 0)
+// CHECK:   ('_indirect_symbols', [
+// CHECK:     # Indirect Symbol 0
+// CHECK:     (('symbol_index', 5),),
+// CHECK:     # Indirect Symbol 1
+// CHECK:     (('symbol_index', 4),),
+// CHECK:     # Indirect Symbol 2
+// CHECK:     (('symbol_index', 0),),
+// CHECK:     # Indirect Symbol 3
+// CHECK:     (('symbol_index', 6),),
+// CHECK:     # Indirect Symbol 4
+// CHECK:     (('symbol_index', 2),),
+// CHECK:     # Indirect Symbol 5
+// CHECK:     (('symbol_index', 8),),
+// CHECK:     # Indirect Symbol 6
+// CHECK:     (('symbol_index', 7),),
+// CHECK:     # Indirect Symbol 7
+// CHECK:     (('symbol_index', 2147483648),),
+// CHECK:     # Indirect Symbol 8
+// CHECK:     (('symbol_index', 9),),
+// CHECK:     # Indirect Symbol 9
+// CHECK:     (('symbol_index', 3),),
+// CHECK:   ])
+// CHECK:  ),
+// CHECK: ])





More information about the llvm-commits mailing list