[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