[llvm-commits] [llvm] r98949 - in /llvm/trunk: include/llvm/MC/MCAssembler.h include/llvm/MC/MCObjectWriter.h lib/MC/CMakeLists.txt lib/MC/MCAssembler.cpp lib/MC/MCObjectWriter.cpp
Daniel Dunbar
daniel at zuster.org
Fri Mar 19 02:28:59 PDT 2010
Author: ddunbar
Date: Fri Mar 19 04:28:59 2010
New Revision: 98949
URL: http://llvm.org/viewvc/llvm-project?rev=98949&view=rev
Log:
MC: Split MCObjectWriter out of MCAssembler.cpp.
Added:
llvm/trunk/include/llvm/MC/MCObjectWriter.h
llvm/trunk/lib/MC/MCObjectWriter.cpp
Modified:
llvm/trunk/include/llvm/MC/MCAssembler.h
llvm/trunk/lib/MC/CMakeLists.txt
llvm/trunk/lib/MC/MCAssembler.cpp
Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=98949&r1=98948&r2=98949&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Fri Mar 19 04:28:59 2010
@@ -26,6 +26,7 @@
class MCContext;
class MCExpr;
class MCFragment;
+class MCObjectWriter;
class MCSection;
class MCSectionData;
class MCSymbol;
@@ -618,6 +619,23 @@
unsigned SubsectionsViaSymbols : 1;
private:
+ /// Evaluate a fixup to a relocatable expression and the value which should be
+ /// placed into the fixup.
+ ///
+ /// \param Layout The layout to use for evaluation.
+ /// \param Fixup The fixup to evaluate.
+ /// \param DF The fragment the fixup is inside.
+ /// \param Target [out] On return, the relocatable expression the fixup
+ /// evaluates to.
+ /// \param Value [out] On return, the value of the fixup as currently layed
+ /// out.
+ /// \return Whether the fixup value was fully resolved. This is true if the
+ /// \arg Value result is fixed, otherwise the value may change due to
+ /// relocation.
+ bool EvaluateFixup(const MCAsmLayout &Layout,
+ MCAsmFixup &Fixup, MCDataFragment *DF,
+ MCValue &Target, uint64_t &Value) const;
+
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
bool FixupNeedsRelaxation(MCAsmFixup &Fixup, MCDataFragment *DF);
@@ -631,7 +649,6 @@
/// were adjusted.
bool LayoutOnce();
- // FIXME: Make protected once we factor out object writer classes.
public:
/// Find the symbol which defines the atom containing given address, inside
/// the given section, or null if there is no such symbol.
@@ -652,22 +669,10 @@
/// defining a separate atom.
bool isSymbolLinkerVisible(const MCSymbolData *SD) const;
- /// Evaluate a fixup to a relocatable expression and the value which should be
- /// placed into the fixup.
- ///
- /// \param Layout The layout to use for evaluation.
- /// \param Fixup The fixup to evaluate.
- /// \param DF The fragment the fixup is inside.
- /// \param Target [out] On return, the relocatable expression the fixup
- /// evaluates to.
- /// \param Value [out] On return, the value of the fixup as currently layed
- /// out.
- /// \return Whether the fixup value was fully resolved. This is true if the
- /// \arg Value result is fixed, otherwise the value may change due to
- /// relocation.
- bool EvaluateFixup(const MCAsmLayout &Layout,
- MCAsmFixup &Fixup, MCDataFragment *DF,
- MCValue &Target, uint64_t &Value) const;
+ /// Emit the section contents using the given object writer.
+ //
+ // FIXME: Should MCAssembler always have a reference to the object writer?
+ void WriteSectionData(const MCSectionData *Section, MCObjectWriter *OW) const;
public:
/// Construct a new assembler instance.
Added: llvm/trunk/include/llvm/MC/MCObjectWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectWriter.h?rev=98949&view=auto
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectWriter.h (added)
+++ llvm/trunk/include/llvm/MC/MCObjectWriter.h Fri Mar 19 04:28:59 2010
@@ -0,0 +1,162 @@
+//===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCOBJECTWRITER_H
+#define LLVM_MC_MCOBJECTWRITER_H
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+class MCAsmFixup;
+class MCAssembler;
+class MCDataFragment;
+class MCValue;
+class raw_ostream;
+
+/// MCObjectWriter - Defines the object file and target independent interfaces
+/// used by the assembler backend to write native file format object files.
+///
+/// The object writer contains a few callbacks used by the assembler to allow
+/// the object writer to modify the assembler data structures at appropriate
+/// points. Once assembly is complete, the object writer is given the
+/// MCAssembler instance, which contains all the symbol and section data which
+/// should be emitted as part of WriteObject().
+///
+/// The object writer also contains a number of helper methods for writing
+/// binary data to the output stream.
+class MCObjectWriter {
+ MCObjectWriter(const MCObjectWriter &); // DO NOT IMPLEMENT
+ void operator=(const MCObjectWriter &); // DO NOT IMPLEMENT
+
+protected:
+ raw_ostream &OS;
+
+ unsigned IsLittleEndian : 1;
+
+protected: // Can only create subclasses.
+ MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
+ : OS(_OS), IsLittleEndian(_IsLittleEndian) {}
+
+public:
+ virtual ~MCObjectWriter();
+
+ bool isLittleEndian() { return IsLittleEndian; }
+
+ raw_ostream &getStream() { return OS; }
+
+ /// @name High-Level API
+ /// @{
+
+ /// Perform any late binding of symbols (for example, to assign symbol indices
+ /// for use when generating relocations).
+ ///
+ /// This routine is called by the assembler after layout and relaxation is
+ /// complete.
+ virtual void ExecutePostLayoutBinding(MCAssembler &Asm) = 0;
+
+ /// Record a relocation entry.
+ ///
+ /// This routine is called by the assembler after layout and relaxation, and
+ /// post layout binding. The implementation is responsible for storing
+ /// information about the relocation so that it can be emitted during
+ /// WriteObject().
+ virtual void RecordRelocation(const MCAssembler &Asm,
+ const MCDataFragment &Fragment,
+ const MCAsmFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue) = 0;
+
+ /// Write the object file.
+ ///
+ /// This routine is called by the assembler after layout and relaxation is
+ /// complete, fixups have been evaluate and applied, and relocations
+ /// generated.
+ virtual void WriteObject(const MCAssembler &Asm) = 0;
+
+ /// @}
+ /// @name Binary Output
+ /// @{
+
+ void Write8(uint8_t Value) {
+ OS << char(Value);
+ }
+
+ void WriteLE16(uint16_t Value) {
+ Write8(uint8_t(Value >> 0));
+ Write8(uint8_t(Value >> 8));
+ }
+
+ void WriteLE32(uint32_t Value) {
+ WriteLE16(uint16_t(Value >> 0));
+ WriteLE16(uint16_t(Value >> 16));
+ }
+
+ void WriteLE64(uint64_t Value) {
+ WriteLE32(uint32_t(Value >> 0));
+ WriteLE32(uint32_t(Value >> 32));
+ }
+
+ void WriteBE16(uint16_t Value) {
+ Write8(uint8_t(Value >> 8));
+ Write8(uint8_t(Value >> 0));
+ }
+
+ void WriteBE32(uint32_t Value) {
+ WriteBE16(uint16_t(Value >> 16));
+ WriteBE16(uint16_t(Value >> 0));
+ }
+
+ void WriteBE64(uint64_t Value) {
+ WriteBE32(uint32_t(Value >> 32));
+ WriteBE32(uint32_t(Value >> 0));
+ }
+
+ void Write16(uint16_t Value) {
+ if (IsLittleEndian)
+ WriteLE16(Value);
+ else
+ WriteBE16(Value);
+ }
+
+ void Write32(uint32_t Value) {
+ if (IsLittleEndian)
+ WriteLE32(Value);
+ else
+ WriteBE32(Value);
+ }
+
+ void Write64(uint64_t Value) {
+ if (IsLittleEndian)
+ WriteLE64(Value);
+ else
+ WriteBE64(Value);
+ }
+
+ void WriteZeros(unsigned N) {
+ const char Zeros[16] = { 0 };
+
+ for (unsigned i = 0, e = N / 16; i != e; ++i)
+ OS << StringRef(Zeros, 16);
+
+ OS << StringRef(Zeros, N % 16);
+ }
+
+ void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
+ OS << Str;
+ if (ZeroFillSize)
+ WriteZeros(ZeroFillSize - Str.size());
+ }
+
+ /// @}
+};
+
+} // End llvm namespace
+
+#endif
Modified: llvm/trunk/lib/MC/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/CMakeLists.txt?rev=98949&r1=98948&r2=98949&view=diff
==============================================================================
--- llvm/trunk/lib/MC/CMakeLists.txt (original)
+++ llvm/trunk/lib/MC/CMakeLists.txt Fri Mar 19 04:28:59 2010
@@ -12,6 +12,7 @@
MCInstPrinter.cpp
MCMachOStreamer.cpp
MCNullStreamer.cpp
+ MCObjectWriter.cpp
MCSection.cpp
MCSectionELF.cpp
MCSectionMachO.cpp
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=98949&r1=98948&r2=98949&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Fri Mar 19 04:28:59 2010
@@ -11,6 +11,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
@@ -42,10 +43,6 @@
// object file, which may truncate it. We should detect that truncation where
// invalid and report errors back.
-class MCObjectWriter;
-static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
- MCObjectWriter *MOW);
-
/// isVirtualSection - Check if this is a section which does not actually exist
/// in the object file.
static bool isVirtualSection(const MCSection &Section) {
@@ -78,105 +75,6 @@
}
}
-class MCObjectWriter {
- MCObjectWriter(const MCObjectWriter &); // DO NOT IMPLEMENT
- void operator=(const MCObjectWriter &); // DO NOT IMPLEMENT
-
-protected:
- raw_ostream &OS;
-
- unsigned IsLittleEndian : 1;
-
-protected: // Can only create subclasses.
- MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
- : OS(_OS), IsLittleEndian(_IsLittleEndian) {}
- virtual ~MCObjectWriter();
-
-public:
-
- bool isLittleEndian() { return IsLittleEndian; }
-
- raw_ostream &getStream() { return OS; }
-
- /// @name Binary Output Methods
- /// @{
-
- void Write8(uint8_t Value) {
- OS << char(Value);
- }
-
- void WriteLE16(uint16_t Value) {
- Write8(uint8_t(Value >> 0));
- Write8(uint8_t(Value >> 8));
- }
-
- void WriteLE32(uint32_t Value) {
- WriteLE16(uint16_t(Value >> 0));
- WriteLE16(uint16_t(Value >> 16));
- }
-
- void WriteLE64(uint64_t Value) {
- WriteLE32(uint32_t(Value >> 0));
- WriteLE32(uint32_t(Value >> 32));
- }
-
- void WriteBE16(uint16_t Value) {
- Write8(uint8_t(Value >> 8));
- Write8(uint8_t(Value >> 0));
- }
-
- void WriteBE32(uint32_t Value) {
- WriteBE16(uint16_t(Value >> 16));
- WriteBE16(uint16_t(Value >> 0));
- }
-
- void WriteBE64(uint64_t Value) {
- WriteBE32(uint32_t(Value >> 32));
- WriteBE32(uint32_t(Value >> 0));
- }
-
- void Write16(uint16_t Value) {
- if (IsLittleEndian)
- WriteLE16(Value);
- else
- WriteBE16(Value);
- }
-
- void Write32(uint32_t Value) {
- if (IsLittleEndian)
- WriteLE32(Value);
- else
- WriteBE32(Value);
- }
-
- void Write64(uint64_t Value) {
- if (IsLittleEndian)
- WriteLE64(Value);
- else
- WriteBE64(Value);
- }
-
- void WriteZeros(unsigned N) {
- const char Zeros[16] = { 0 };
-
- for (unsigned i = 0, e = N / 16; i != e; ++i)
- OS << StringRef(Zeros, 16);
-
- OS << StringRef(Zeros, N % 16);
- }
-
- void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
- OS << Str;
- if (ZeroFillSize)
- WriteZeros(ZeroFillSize - Str.size());
- }
-
- /// @}
-};
-
-MCObjectWriter::~MCObjectWriter() {
-}
-
class MachObjectWriter : public MCObjectWriter {
// See <mach-o/loader.h>.
enum {
@@ -362,8 +260,9 @@
assert(OS.tell() - Start == SegmentLoadCommandSize);
}
- void WriteSection(const MCSectionData &SD, uint64_t FileOffset,
- uint64_t RelocationsStart, unsigned NumRelocations) {
+ void WriteSection(const MCAssembler &Asm, const MCSectionData &SD,
+ uint64_t FileOffset, uint64_t RelocationsStart,
+ unsigned NumRelocations) {
// The offset is unused for virtual sections.
if (isVirtualSection(SD.getSection())) {
assert(SD.getFileSize() == 0 && "Invalid file size!");
@@ -527,7 +426,8 @@
Write32(Address);
}
- void RecordScatteredRelocation(MCAssembler &Asm, MCFragment &Fragment,
+ void RecordScatteredRelocation(const MCAssembler &Asm,
+ const MCFragment &Fragment,
const MCAsmFixup &Fixup, MCValue Target,
uint64_t &FixedValue) {
uint32_t Address = Fragment.getOffset() + Fixup.Offset;
@@ -584,9 +484,10 @@
Relocations[Fragment.getParent()].push_back(MRE);
}
- void RecordRelocation(MCAssembler &Asm, MCDataFragment &Fragment,
- const MCAsmFixup &Fixup, MCValue Target,
- uint64_t &FixedValue) {
+ virtual void RecordRelocation(const MCAssembler &Asm,
+ const MCDataFragment &Fragment,
+ const MCAsmFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue) {
unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
@@ -629,7 +530,7 @@
//
// FIXME: O(N)
Index = 1;
- MCAssembler::iterator it = Asm.begin(), ie = Asm.end();
+ MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
for (; it != ie; ++it, ++Index)
if (&*it == SD->getFragment()->getParent())
break;
@@ -807,7 +708,7 @@
StringTable += '\x00';
}
- void ExecutePostLayoutBinding(MCAssembler &Asm) {
+ virtual void ExecutePostLayoutBinding(MCAssembler &Asm) {
// Create symbol data for any indirect symbols.
BindIndirectSymbols(Asm);
@@ -816,7 +717,7 @@
UndefinedSymbolData);
}
- void WriteObject(const MCAssembler &Asm) {
+ virtual void WriteObject(const MCAssembler &Asm) {
unsigned NumSections = Asm.size();
// The section data starts after the header, the segment load command (and
@@ -916,7 +817,7 @@
// Write the actual section data.
for (MCAssembler::const_iterator it = Asm.begin(),
ie = Asm.end(); it != ie; ++it)
- WriteFileData(OS, *it, this);
+ Asm.WriteSectionData(it, this);
// Write the extra padding.
WriteZeros(SectionDataPadding);
@@ -1357,10 +1258,9 @@
return Count;
}
-/// WriteFileData - Write the \arg F data to the output file.
-static void WriteFileData(raw_ostream &OS, const MCFragment &F,
- MCObjectWriter *OW) {
- uint64_t Start = OS.tell();
+/// WriteFragmentData - Write the \arg F data to the output file.
+static void WriteFragmentData(const MCFragment &F, MCObjectWriter *OW) {
+ uint64_t Start = OW->getStream().tell();
(void) Start;
++EmittedFragments;
@@ -1402,7 +1302,7 @@
}
case MCFragment::FT_Data: {
- OS << cast<MCDataFragment>(F).getContents().str();
+ OW->WriteBytes(cast<MCDataFragment>(F).getContents().str());
break;
}
@@ -1436,30 +1336,29 @@
}
}
- assert(OS.tell() - Start == F.getFileSize());
+ assert(OW->getStream().tell() - Start == F.getFileSize());
}
-/// WriteFileData - Write the \arg SD data to the output file.
-static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
- MCObjectWriter *OW) {
+void MCAssembler::WriteSectionData(const MCSectionData *SD,
+ MCObjectWriter *OW) const {
// Ignore virtual sections.
- if (isVirtualSection(SD.getSection())) {
- assert(SD.getFileSize() == 0);
+ if (isVirtualSection(SD->getSection())) {
+ assert(SD->getFileSize() == 0);
return;
}
- uint64_t Start = OS.tell();
+ uint64_t Start = OW->getStream().tell();
(void) Start;
- for (MCSectionData::const_iterator it = SD.begin(),
- ie = SD.end(); it != ie; ++it)
- WriteFileData(OS, *it, OW);
+ for (MCSectionData::const_iterator it = SD->begin(),
+ ie = SD->end(); it != ie; ++it)
+ WriteFragmentData(*it, OW);
// Add section padding.
- assert(SD.getFileSize() >= SD.getSize() && "Invalid section sizes!");
- OW->WriteZeros(SD.getFileSize() - SD.getSize());
+ assert(SD->getFileSize() >= SD->getSize() && "Invalid section sizes!");
+ OW->WriteZeros(SD->getFileSize() - SD->getSize());
- assert(OS.tell() - Start == SD.getFileSize());
+ assert(OW->getStream().tell() - Start == SD->getFileSize());
}
void MCAssembler::Finish() {
Added: llvm/trunk/lib/MC/MCObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectWriter.cpp?rev=98949&view=auto
==============================================================================
--- llvm/trunk/lib/MC/MCObjectWriter.cpp (added)
+++ llvm/trunk/lib/MC/MCObjectWriter.cpp Fri Mar 19 04:28:59 2010
@@ -0,0 +1,15 @@
+//===- lib/MC/MCObjetWriter.cpp - MCObjetWriter implementation ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCObjectWriter.h"
+
+using namespace llvm;
+
+MCObjectWriter::~MCObjectWriter() {
+}
More information about the llvm-commits
mailing list