diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-08-28 07:08:35 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-08-28 07:08:35 +0000 |
commit | 8f4d146c340c9423271ebd7bb3fd32b880000bc9 (patch) | |
tree | 30e828d8e7786804767d1d4b326d6525068b0edf /lib/MC/MCAssembler.cpp | |
parent | d17479e8458d17575e2532d9e8a61057b057a33d (diff) |
llvm-mc: Support .comm emission.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80351 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCAssembler.cpp')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 8057fcb359..0d9b540d15 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -25,6 +25,11 @@ class MachObjectWriter; STATISTIC(EmittedFragments, "Number of emitted assembler fragments"); +// FIXME FIXME FIXME: There are number of places in this file where we convert +// what is a 64-bit assembler value used for computation into a value in the +// object file, which may truncate it. We should detect that truncation where +// invalid and report errors back. + static void WriteFileData(raw_ostream &OS, const MCSectionData &SD, MachObjectWriter &MOW); @@ -328,6 +333,8 @@ public: MCSymbolData &Data = *MSD.SymbolData; MCSymbol &Symbol = Data.getSymbol(); uint8_t Type = 0; + uint16_t Flags = Data.getFlags(); + uint32_t Address = 0; // Set the N_TYPE bits. See <mach-o/nlist.h>. // @@ -348,6 +355,30 @@ public: if (Data.isExternal() || Symbol.isUndefined()) Type |= STF_External; + // Compute the symbol address. + if (Symbol.isDefined()) { + if (Symbol.isAbsolute()) { + llvm_unreachable("FIXME: Not yet implemented!"); + } else { + Address = Data.getFragment()->getAddress() + Data.getOffset(); + } + } else if (Data.isCommon()) { + // Common symbols are encoded with the size in the address + // field, and their alignment in the flags. + Address = Data.getCommonSize(); + + // Common alignment is packed into the 'desc' bits. + if (unsigned Align = Data.getCommonAlignment()) { + unsigned Log2Size = Log2_32(Align); + assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); + if (Log2Size > 15) + llvm_report_error("invalid 'common' alignment '" + + Twine(Align) + "'"); + // FIXME: Keep this mask with the SymbolFlags enumeration. + Flags = (Flags & 0xF0FF) | (Log2Size << 8); + } + } + // struct nlist (12 bytes) Write32(MSD.StringIndex); @@ -356,17 +387,7 @@ public: // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' // value. - Write16(Data.getFlags() & 0xFFFF); - - // Write the symbol address. - uint32_t Address = 0; - if (Symbol.isDefined()) { - if (Symbol.isAbsolute()) { - llvm_unreachable("FIXME: Not yet implemented!"); - } else { - Address = Data.getFragment()->getAddress() + Data.getOffset(); - } - } + Write16(Flags); Write32(Address); } @@ -910,7 +931,8 @@ MCSymbolData::MCSymbolData() : Symbol(*(MCSymbol*)0) {} MCSymbolData::MCSymbolData(MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset, MCAssembler *A) : Symbol(_Symbol), Fragment(_Fragment), Offset(_Offset), - IsExternal(false), IsPrivateExtern(false), Flags(0), Index(0) + IsExternal(false), IsPrivateExtern(false), + CommonSize(0), CommonAlign(0), Flags(0), Index(0) { if (A) A->getSymbolList().push_back(this); |