[llvm-commits] [llvm] r79733 - in /llvm/trunk: include/llvm/MC/MCSymbol.h include/llvm/MC/MCValue.h lib/MC/MCAsmStreamer.cpp lib/MC/MCMachOStreamer.cpp lib/MC/MCSymbol.cpp test/Scripts/macho-dump tools/llvm-mc/AsmParser.cpp

Daniel Dunbar daniel at zuster.org
Sat Aug 22 00:22:41 PDT 2009


Author: ddunbar
Date: Sat Aug 22 02:22:36 2009
New Revision: 79733

URL: http://llvm.org/viewvc/llvm-project?rev=79733&view=rev
Log:
llvm-mc: Clean up some handling of symbol/section association to be more correct
(external was really undefined and there wasn't an explicit representation for
absolute symbols).
 - This still needs some cleanup to how the absolute "pseudo" section is dealt
   with, but I haven't figured out the nicest approach yet.

Modified:
    llvm/trunk/include/llvm/MC/MCSymbol.h
    llvm/trunk/include/llvm/MC/MCValue.h
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCMachOStreamer.cpp
    llvm/trunk/lib/MC/MCSymbol.cpp
    llvm/trunk/test/Scripts/macho-dump
    llvm/trunk/tools/llvm-mc/AsmParser.cpp

Modified: llvm/trunk/include/llvm/MC/MCSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSymbol.h?rev=79733&r1=79732&r2=79733&view=diff

==============================================================================
--- llvm/trunk/include/llvm/MC/MCSymbol.h (original)
+++ llvm/trunk/include/llvm/MC/MCSymbol.h Sat Aug 22 02:22:36 2009
@@ -16,6 +16,7 @@
 
 #include <string>
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
 
 namespace llvm {
   class MCSection;
@@ -30,38 +31,68 @@
   /// it is a reference to an external entity, it has a null section.  
   /// 
   class MCSymbol {
+    // Special sentinal value for the absolute pseudo section.
+    //
+    // FIXME: Use a PointerInt wrapper for this?
+    static const MCSection *AbsolutePseudoSection;
+
     /// Name - The name of the symbol.
     std::string Name;
-    /// Section - The section the symbol is defined in, or null if the symbol
-    /// has not been defined in the associated translation unit.
+
+    /// Section - The section the symbol is defined in. This is null for
+    /// undefined symbols, and the special AbsolutePseudoSection value for
+    /// absolute symbols.
     const MCSection *Section;
     
     /// IsTemporary - True if this is an assembler temporary label, which
     /// typically does not survive in the .o file's symbol table.  Usually
     /// "Lfoo" or ".foo".
     unsigned IsTemporary : 1;
-    
-    /// IsExternal - True if this symbol has been implicitly defined as an
-    /// external, for example by using it in an expression without ever emitting
-    /// it as a label. The @var Section for an external symbol is always null.
-    unsigned IsExternal : 1;
 
   private:  // MCContext creates and uniques these.
     friend class MCContext;
     MCSymbol(const StringRef &_Name, bool _IsTemporary) 
-      : Name(_Name), Section(0), IsTemporary(_IsTemporary), IsExternal(false) {}
+      : Name(_Name), Section(0),
+        IsTemporary(_IsTemporary) {}
     
     MCSymbol(const MCSymbol&);       // DO NOT IMPLEMENT
     void operator=(const MCSymbol&); // DO NOT IMPLEMENT
   public:
-    
-    const MCSection *getSection() const { return Section; }
-    void setSection(const MCSection *S) { Section = S; }
+    /// getName - Get the symbol name.
+    const std::string &getName() const { return Name; }
 
-    bool isExternal() const { return IsExternal; }
-    void setExternal(bool Value) { IsExternal = Value; }
+    /// @name Symbol Location Functions
+    /// @{
 
-    const std::string &getName() const { return Name; }
+    /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
+    bool isUndefined() const {
+      return Section == 0;
+    }
+
+    /// isAbsolute - Check if this this is an absolute symbol.
+    bool isAbsolute() const {
+      return Section == AbsolutePseudoSection;
+    }
+
+    /// getSection - Get the section associated with a defined, non-absolute
+    /// symbol.
+    const MCSection &getSection() const {
+      assert(!isUndefined() && !isAbsolute() && "Invalid accessor!");
+      return *Section;
+    }
+
+    /// setSection - Mark the symbol as defined in the section \arg S.
+    void setSection(const MCSection &S) { Section = &S; }
+
+    /// setUndefined - Mark the symbol as undefined.
+    void setUndefined() {
+      Section = 0;
+    }
+
+    /// setAbsolute - Mark the symbol as absolute.
+    void setAbsolute() { Section = AbsolutePseudoSection; }
+
+    /// @}
 
     /// print - Print the value to the stream \arg OS.
     void print(raw_ostream &OS) const;

Modified: llvm/trunk/include/llvm/MC/MCValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCValue.h?rev=79733&r1=79732&r2=79733&view=diff

==============================================================================
--- llvm/trunk/include/llvm/MC/MCValue.h (original)
+++ llvm/trunk/include/llvm/MC/MCValue.h Sat Aug 22 02:22:36 2009
@@ -49,9 +49,10 @@
   ///
   /// @result - The value's associated section, or null for external or constant
   /// values.
-  const MCSection *getAssociatedSection() const {
-    return SymA ? SymA->getSection() : 0;
-  }
+  //
+  // FIXME: Switch to a tagged section, so this can return the tagged section
+  // value.
+  const MCSection *getAssociatedSection() const;
 
   /// print - Print the value to the stream \arg OS.
   void print(raw_ostream &OS) const;

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=79733&r1=79732&r2=79733&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Sat Aug 22 02:22:36 2009
@@ -107,14 +107,11 @@
 }
 
 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
-  assert(Symbol->getSection() == 0 && "Cannot emit a symbol twice!");
+  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
   assert(CurSection && "Cannot emit before setting section!");
-  assert(!getContext().GetSymbolValue(Symbol) && 
-         "Cannot emit symbol which was directly assigned to!");
 
   OS << Symbol << ":\n";
-  Symbol->setSection(CurSection);
-  Symbol->setExternal(false);
+  Symbol->setSection(*CurSection);
 }
 
 void MCAsmStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
@@ -127,7 +124,9 @@
 
 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCValue &Value,
                                    bool MakeAbsolute) {
-  assert(!Symbol->getSection() && "Cannot assign to a label!");
+  // Only absolute symbols can be redefined.
+  assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
+         "Cannot define a symbol twice!");
 
   if (MakeAbsolute) {
     OS << ".set " << Symbol << ", " << Value << '\n';

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

==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Sat Aug 22 02:22:36 2009
@@ -91,15 +91,12 @@
 }
 
 void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
-  assert(Symbol->getSection() == 0 && "Cannot emit a symbol twice!");
+  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
   assert(CurSection && "Cannot emit before setting section!");
-  assert(!getContext().GetSymbolValue(Symbol) &&
-         "Cannot emit symbol which was directly assigned to!");
 
   llvm_unreachable("FIXME: Not yet implemented!");
 
-  Symbol->setSection(CurSection);
-  Symbol->setExternal(false);
+  Symbol->setSection(*CurSection);
 }
 
 void MCMachOStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
@@ -109,7 +106,9 @@
 void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol,
                                      const MCValue &Value,
                                      bool MakeAbsolute) {
-  assert(!Symbol->getSection() && "Cannot assign to a label!");
+  // Only absolute symbols can be redefined.
+  assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
+         "Cannot define a symbol twice!");
 
   llvm_unreachable("FIXME: Not yet implemented!");
 }

Modified: llvm/trunk/lib/MC/MCSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSymbol.cpp?rev=79733&r1=79732&r2=79733&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCSymbol.cpp (original)
+++ llvm/trunk/lib/MC/MCSymbol.cpp Sat Aug 22 02:22:36 2009
@@ -12,6 +12,10 @@
 
 using namespace llvm;
 
+// Sentinel value for the absolute pseudo section.
+const MCSection *MCSymbol::AbsolutePseudoSection =
+  reinterpret_cast<const MCSection *>(1);
+
 /// NeedsQuoting - Return true if the string \arg Str needs quoting, i.e., it
 /// does not match [a-zA-Z_.][a-zA-Z0-9_.]*.
 //

Modified: llvm/trunk/test/Scripts/macho-dump
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Scripts/macho-dump?rev=79733&r1=79732&r2=79733&view=diff

==============================================================================
--- llvm/trunk/test/Scripts/macho-dump (original)
+++ llvm/trunk/test/Scripts/macho-dump Sat Aug 22 02:22:36 2009
@@ -2,32 +2,56 @@
 
 import struct
 import sys
+import StringIO
 
 class Reader:
    def __init__(self, path):
       if path == '-':
-         self.file = sys.stdin
+         # Snarf all the data so we can seek.
+         self.file = StringIO.StringIO(sys.stdin.read())
       else:
          self.file = open(path,'rb')
       self.isLSB = None
-      self.pos = 0
+
+      self.string_table = None
 
    def setLSB(self, isLSB):
       self.isLSB = bool(isLSB)
 
    def tell(self):
-      return self.pos
+      return self.file.tell()
+
+   def seek(self, pos):
+      self.file.seek(pos)
 
    def read(self, N):
       data = self.file.read(N)
-      self.pos += len(data)
       if len(data) != N:
          raise ValueError,"Out of data!"
       return data
 
+   def read8(self):
+      return ord(self.read(1))
+
+   def read16(self):
+      return struct.unpack('><'[self.isLSB] + 'H', self.read(2))[0]
+
    def read32(self):
       return struct.unpack('><'[self.isLSB] + 'I', self.read(4))[0]
 
+   def registerStringTable(self, strings):
+      if self.string_table is not None:
+         raise ValueError,"%s: warning: multiple string tables" % sys.argv[0]
+
+      self.string_table = strings
+
+   def getString(self, index):
+      if self.string_table is None:
+         raise ValueError,"%s: warning: no string table registered" % sys.argv[0]
+      
+      end = self.string_table.index('\x00', index)
+      return self.string_table[index:end]
+
 def dumpmacho(path, opts):
    f = Reader(path)
 
@@ -60,7 +84,7 @@
    print "])"
 
    if f.tell() - start != loadCommandsSize:
-      raise ValueError,"%s: warning: invalid load commands size: %r" % (sys.argv, loadCommandsSize)
+      raise ValueError,"%s: warning: invalid load commands size: %r" % (sys.argv[0], loadCommandsSize)
 
 def dumpLoadCommand(f, i, opts):
    start = f.tell()
@@ -83,7 +107,7 @@
    print " ),"
 
    if f.tell() - start != cmdSize:
-      raise ValueError,"%s: warning: invalid load command size: %r" % (sys.argv, cmdSize)
+      raise ValueError,"%s: warning: invalid load command size: %r" % (sys.argv[0], cmdSize)
 
 def dumpSegmentLoadCommand32(f, opts):
    print "  ('segment_name', %r)" % f.read(16) 
@@ -103,10 +127,45 @@
    print "  ])"
 
 def dumpSymtabCommand(f, opts):
-   print "  ('symoff', %r)" % f.read32()
-   print "  ('nsyms', %r)" % f.read32()
-   print "  ('stroff', %r)" % f.read32()
-   print "  ('strsize', %r)" % f.read32()
+   symoff = f.read32()
+   print "  ('symoff', %r)" % symoff
+   nsyms = f.read32()
+   print "  ('nsyms', %r)" % nsyms
+   stroff = f.read32()
+   print "  ('stroff', %r)" % stroff
+   strsize = f.read32()
+   print "  ('strsize', %r)" % strsize
+
+   prev_pos = f.tell()
+
+   f.seek(stroff)
+   string_data = f.read(strsize)
+   print "  ('_string_data', %r)" % string_data
+
+   f.registerStringTable(string_data)
+
+   f.seek(symoff)
+   print "  ('_symbols', ["
+   for i in range(nsyms):
+      dumpNlist32(f, i, opts)
+   print "  ])"
+      
+   f.seek(prev_pos)
+
+def dumpNlist32(f, i, opts):
+   print "    # Symbol %r" % i
+   n_strx = f.read32()
+   print "   (('n_strx', %r)" % n_strx
+   n_type = f.read8()
+   print "    ('n_type', %#x)" % n_type
+   n_sect = f.read8()
+   print "    ('n_type', %r)" % n_sect
+   n_desc = f.read16()
+   print "    ('n_desc', %r)" % n_desc
+   n_value = f.read32()
+   print "    ('n_value', %r)" % n_value
+   print "    ('_string', %r)" % f.getString(n_strx)
+   print "   ),"
 
 def dumpDysymtabCommand(f, opts):   
    print "  ('ilocalsym', %r)" % f.read32()
@@ -121,13 +180,26 @@
    print "  ('nmodtab', %r)" % f.read32()
    print "  ('extrefsymoff', %r)" % f.read32()
    print "  ('nextrefsyms', %r)" % f.read32()
-   print "  ('indirectsymoff', %r)" % f.read32()
-   print "  ('nindirectsyms', %r)" % f.read32()
+   indirectsymoff = f.read32()
+   print "  ('indirectsymoff', %r)" % indirectsymoff
+   nindirectsyms = f.read32()
+   print "  ('nindirectsyms', %r)" % nindirectsyms
    print "  ('extreloff', %r)" % f.read32()
    print "  ('nextrel', %r)" % f.read32()
    print "  ('locreloff', %r)" % f.read32()
    print "  ('nlocrel', %r)" % f.read32()
 
+   prev_pos = f.tell()
+
+   f.seek(indirectsymoff)
+   print "  ('_indirect_symbols', ["
+   for i in range(nindirectsyms):
+      print "    # Indirect Symbol %r" % i
+      print "    (('symbol_index', %r),)," % f.read32()
+   print "  ])"
+      
+   f.seek(prev_pos)
+
 def dumpSection32(f, i, opts):
    print "    # Section %r" % i
    print "   (('section_name', %r)" % f.read(16)

Modified: llvm/trunk/tools/llvm-mc/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/AsmParser.cpp?rev=79733&r1=79732&r2=79733&view=diff

==============================================================================
--- llvm/trunk/tools/llvm-mc/AsmParser.cpp (original)
+++ llvm/trunk/tools/llvm-mc/AsmParser.cpp Sat Aug 22 02:22:36 2009
@@ -149,10 +149,6 @@
     // This is a label, this should be parsed as part of an expression, to
     // handle things like LFOO+4.
     MCSymbol *Sym = Ctx.GetOrCreateSymbol(Lexer.getTok().getIdentifier());
-
-    // If this is use of an undefined symbol then mark it external.
-    if (!Sym->getSection() && !Ctx.GetSymbolValue(Sym))
-      Sym->setExternal(true);
     
     Res = new AsmSymbolRefExpr(Sym);
     Lexer.Lex(); // Eat identifier.
@@ -376,10 +372,8 @@
     // FIXME: This doesn't diagnose assignment to a symbol which has been
     // implicitly marked as external.
     MCSymbol *Sym = Ctx.GetOrCreateSymbol(IDVal);
-    if (Sym->getSection())
+    if (!Sym->isUndefined())
       return Error(IDLoc, "invalid symbol redefinition");
-    if (Ctx.GetSymbolValue(Sym))
-      return Error(IDLoc, "symbol already used as assembler variable");
     
     // Since we saw a label, create a symbol and emit it.
     // FIXME: If the label starts with L it is an assembler temporary label.
@@ -687,15 +681,11 @@
   // Diagnose assignment to a label.
   //
   // FIXME: Diagnostics. Note the location of the definition as a label.
-  // FIXME: This doesn't diagnose assignment to a symbol which has been
-  // implicitly marked as external.
   // FIXME: Handle '.'.
   // FIXME: Diagnose assignment to protected identifier (e.g., register name).
   MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name);
-  if (Sym->getSection())
-    return Error(EqualLoc, "invalid assignment to symbol emitted as a label");
-  if (Sym->isExternal())
-    return Error(EqualLoc, "invalid assignment to external symbol");
+  if (!Sym->isUndefined() && !Sym->isAbsolute())
+    return Error(EqualLoc, "symbol has already been defined");
 
   // Do the assignment.
   Out.EmitAssignment(Sym, Value, IsDotSet);
@@ -1117,10 +1107,6 @@
       
       MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name);
 
-      // If this is use of an undefined symbol then mark it external.
-      if (!Sym->getSection() && !Ctx.GetSymbolValue(Sym))
-        Sym->setExternal(true);
-
       Out.EmitSymbolAttribute(Sym, Attr);
 
       if (Lexer.is(AsmToken::EndOfStatement))
@@ -1213,8 +1199,7 @@
     return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
                  "alignment, can't be less than zero");
 
-  // TODO: Symbol must be undefined or it is a error to re-defined the symbol
-  if (Sym->getSection() || Ctx.GetSymbolValue(Sym))
+  if (!Sym->isUndefined())
     return Error(IDLoc, "invalid symbol redefinition");
 
   // Create the Symbol as a common or local common with Size and Pow2Alignment
@@ -1305,8 +1290,7 @@
     return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
                  "can't be less than zero");
 
-  // TODO: Symbol must be undefined or it is a error to re-defined the symbol
-  if (Sym->getSection() || Ctx.GetSymbolValue(Sym))
+  if (!Sym->isUndefined())
     return Error(IDLoc, "invalid symbol redefinition");
 
   // FIXME: Arch specific.





More information about the llvm-commits mailing list