aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-03-19 09:28:55 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-03-19 09:28:55 +0000
commitbdd9281f356d326155dc2ca5585a708e09e90600 (patch)
tree40e49a642a996dfcf1bce6ba91ca79e6c2d4bcb7
parent87190c473c216e481e0a70475577e496b3a3449e (diff)
downloadexternal_llvm-bdd9281f356d326155dc2ca5585a708e09e90600.zip
external_llvm-bdd9281f356d326155dc2ca5585a708e09e90600.tar.gz
external_llvm-bdd9281f356d326155dc2ca5585a708e09e90600.tar.bz2
MCAssembler: Pull out MCObjectWriter class.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98948 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/MC/MCAssembler.cpp208
1 files changed, 126 insertions, 82 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index c4c3a8a..ad42364 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -42,10 +42,9 @@ STATISTIC(EmittedFragments, "Number of emitted assembler fragments");
// 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,
- MachObjectWriter &MOW);
-
-static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW);
+ MCObjectWriter *MOW);
/// isVirtualSection - Check if this is a section which does not actually exist
/// in the object file.
@@ -79,7 +78,106 @@ static bool isFixupKindPCRel(unsigned Kind) {
}
}
-class MachObjectWriter {
+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 {
Header_Magic32 = 0xFEEDFACE,
@@ -166,9 +264,7 @@ class MachObjectWriter {
}
};
- raw_ostream &OS;
unsigned Is64Bit : 1;
- unsigned IsLSB : 1;
/// @name Relocation Data
/// @{
@@ -192,64 +288,10 @@ class MachObjectWriter {
/// @}
public:
- MachObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool _IsLSB = true)
- : OS(_OS), Is64Bit(_Is64Bit), IsLSB(_IsLSB) {
+ MachObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool _IsLittleEndian = true)
+ : MCObjectWriter(_OS, _IsLittleEndian), Is64Bit(_Is64Bit) {
}
- /// @name Helper Methods
- /// @{
-
- void Write8(uint8_t Value) {
- OS << char(Value);
- }
-
- void Write16(uint16_t Value) {
- if (IsLSB) {
- Write8(uint8_t(Value >> 0));
- Write8(uint8_t(Value >> 8));
- } else {
- Write8(uint8_t(Value >> 8));
- Write8(uint8_t(Value >> 0));
- }
- }
-
- void Write32(uint32_t Value) {
- if (IsLSB) {
- Write16(uint16_t(Value >> 0));
- Write16(uint16_t(Value >> 16));
- } else {
- Write16(uint16_t(Value >> 16));
- Write16(uint16_t(Value >> 0));
- }
- }
-
- void Write64(uint64_t Value) {
- if (IsLSB) {
- Write32(uint32_t(Value >> 0));
- Write32(uint32_t(Value >> 32));
- } else {
- Write32(uint32_t(Value >> 32));
- Write32(uint32_t(Value >> 0));
- }
- }
-
- 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 WriteString(StringRef Str, unsigned ZeroFillSize = 0) {
- OS << Str;
- if (ZeroFillSize)
- WriteZeros(ZeroFillSize - Str.size());
- }
-
- /// @}
-
void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
bool SubsectionsViaSymbols) {
uint32_t Flags = 0;
@@ -300,7 +342,7 @@ public:
Write32(SegmentLoadCommandSize +
NumSections * (Is64Bit ? Section64Size : Section32Size));
- WriteString("", 16);
+ WriteBytes("", 16);
if (Is64Bit) {
Write64(0); // vmaddr
Write64(VMSize); // vmsize
@@ -337,8 +379,8 @@ public:
// FIXME: cast<> support!
const MCSectionMachO &Section =
static_cast<const MCSectionMachO&>(SD.getSection());
- WriteString(Section.getSectionName(), 16);
- WriteString(Section.getSegmentName(), 16);
+ WriteBytes(Section.getSectionName(), 16);
+ WriteBytes(Section.getSegmentName(), 16);
if (Is64Bit) {
Write64(SD.getAddress()); // address
Write64(SD.getSize()); // size
@@ -874,7 +916,7 @@ public:
// Write the actual section data.
for (MCAssembler::const_iterator it = Asm.begin(),
ie = Asm.end(); it != ie; ++it)
- WriteFileData(OS, *it, *this);
+ WriteFileData(OS, *it, this);
// Write the extra padding.
WriteZeros(SectionDataPadding);
@@ -1262,7 +1304,7 @@ void MCAssembler::LayoutSection(MCSectionData &SD) {
/// the \arg Count is more than the maximum optimal nops.
///
/// FIXME this is X86 32-bit specific and should move to a better place.
-static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW) {
+static uint64_t WriteNopData(uint64_t Count, MCObjectWriter *OW) {
static const uint8_t Nops[16][16] = {
// nop
{0x90},
@@ -1310,14 +1352,14 @@ static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW) {
return 0;
for (uint64_t i = 0; i < Count; i++)
- MOW.Write8 (uint8_t(Nops[Count - 1][i]));
+ OW->Write8(uint8_t(Nops[Count - 1][i]));
return Count;
}
/// WriteFileData - Write the \arg F data to the output file.
static void WriteFileData(raw_ostream &OS, const MCFragment &F,
- MachObjectWriter &MOW) {
+ MCObjectWriter *OW) {
uint64_t Start = OS.tell();
(void) Start;
@@ -1342,7 +1384,7 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F,
// the Count bytes. Then if that did not fill any bytes or there are any
// bytes left to fill use the the Value and ValueSize to fill the rest.
if (AF.getEmitNops()) {
- uint64_t NopByteCount = WriteNopData(Count, MOW);
+ uint64_t NopByteCount = WriteNopData(Count, OW);
Count -= NopByteCount;
}
@@ -1350,10 +1392,10 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F,
switch (AF.getValueSize()) {
default:
assert(0 && "Invalid size!");
- case 1: MOW.Write8 (uint8_t (AF.getValue())); break;
- case 2: MOW.Write16(uint16_t(AF.getValue())); break;
- case 4: MOW.Write32(uint32_t(AF.getValue())); break;
- case 8: MOW.Write64(uint64_t(AF.getValue())); break;
+ case 1: OW->Write8 (uint8_t (AF.getValue())); break;
+ case 2: OW->Write16(uint16_t(AF.getValue())); break;
+ case 4: OW->Write32(uint32_t(AF.getValue())); break;
+ case 8: OW->Write64(uint64_t(AF.getValue())); break;
}
}
break;
@@ -1370,10 +1412,10 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F,
switch (FF.getValueSize()) {
default:
assert(0 && "Invalid size!");
- case 1: MOW.Write8 (uint8_t (FF.getValue())); break;
- case 2: MOW.Write16(uint16_t(FF.getValue())); break;
- case 4: MOW.Write32(uint32_t(FF.getValue())); break;
- case 8: MOW.Write64(uint64_t(FF.getValue())); break;
+ case 1: OW->Write8 (uint8_t (FF.getValue())); break;
+ case 2: OW->Write16(uint16_t(FF.getValue())); break;
+ case 4: OW->Write32(uint32_t(FF.getValue())); break;
+ case 8: OW->Write64(uint64_t(FF.getValue())); break;
}
}
break;
@@ -1383,7 +1425,7 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F,
MCOrgFragment &OF = cast<MCOrgFragment>(F);
for (uint64_t i = 0, e = OF.getFileSize(); i != e; ++i)
- MOW.Write8(uint8_t(OF.getValue()));
+ OW->Write8(uint8_t(OF.getValue()));
break;
}
@@ -1399,7 +1441,7 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F,
/// WriteFileData - Write the \arg SD data to the output file.
static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
- MachObjectWriter &MOW) {
+ MCObjectWriter *OW) {
// Ignore virtual sections.
if (isVirtualSection(SD.getSection())) {
assert(SD.getFileSize() == 0);
@@ -1411,11 +1453,11 @@ static void WriteFileData(raw_ostream &OS, const MCSectionData &SD,
for (MCSectionData::const_iterator it = SD.begin(),
ie = SD.end(); it != ie; ++it)
- WriteFileData(OS, *it, MOW);
+ WriteFileData(OS, *it, OW);
// Add section padding.
assert(SD.getFileSize() >= SD.getSize() && "Invalid section sizes!");
- MOW.WriteZeros(SD.getFileSize() - SD.getSize());
+ OW->WriteZeros(SD.getFileSize() - SD.getSize());
assert(OS.tell() - Start == SD.getFileSize());
}
@@ -1442,6 +1484,8 @@ void MCAssembler::Finish() {
MOW.ExecutePostLayoutBinding(*this);
// Evaluate and apply the fixups, generating relocation entries as necessary.
+ //
+ // FIXME: Share layout object.
MCAsmLayout Layout(*this);
for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) {
for (MCSectionData::iterator it2 = it->begin(),