summaryrefslogtreecommitdiffstats
path: root/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCAsmInfo.cpp3
-rw-r--r--lib/MC/MCAsmInfoDarwin.cpp11
-rw-r--r--lib/MC/MCAssembler.cpp90
-rw-r--r--lib/MC/MCContext.cpp21
-rw-r--r--lib/MC/MCExpr.cpp5
-rw-r--r--lib/MC/MCNullStreamer.cpp6
-rw-r--r--lib/MC/MCParser/AsmParser.cpp8
-rw-r--r--lib/MC/MCStreamer.cpp5
8 files changed, 88 insertions, 61 deletions
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index f3f063f..bda700b 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -68,9 +68,6 @@ MCAsmInfo::MCAsmInfo() {
ExceptionsType = ExceptionHandling::None;
DwarfRequiresFrameSection = true;
DwarfUsesInlineInfoSection = false;
- Is_EHSymbolPrivate = true;
- GlobalEHDirective = 0;
- SupportsWeakOmittedEHFrame = true;
DwarfSectionOffsetDirective = 0;
AsmTransCBE = 0;
diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp
index da865ad..3c31caa 100644
--- a/lib/MC/MCAsmInfoDarwin.cpp
+++ b/lib/MC/MCAsmInfoDarwin.cpp
@@ -40,19 +40,8 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
HiddenVisibilityAttr = MCSA_PrivateExtern;
// Doesn't support protected visibility.
ProtectedVisibilityAttr = MCSA_Global;
-
HasDotTypeDotSizeDirective = false;
HasNoDeadStrip = true;
- // Note: Even though darwin has the .lcomm directive, it is just a synonym for
- // zerofill, so we prefer to use .zerofill.
-
- // _foo.eh symbols are currently always exported so that the linker knows
- // about them. This is not necessary on 10.6 and later, but it
- // doesn't hurt anything.
- // FIXME: I need to get this from Triple.
- Is_EHSymbolPrivate = false;
- GlobalEHDirective = "\t.globl\t";
- SupportsWeakOmittedEHFrame = false;
}
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 96227db..00b02e0 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -440,29 +440,49 @@ public:
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
std::vector<MachRelocationEntry> &Relocs) {
uint32_t Address = Fragment.getOffset() + Fixup.Offset;
- unsigned IsPCRel = 0;
+ unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
unsigned Type = RIT_Vanilla;
// See <reloc.h>.
const MCSymbol *A = Target.getSymA();
- MCSymbolData *SD = SymbolMap.lookup(A);
- uint32_t Value = SD->getFragment()->getAddress() + SD->getOffset();
+ MCSymbolData *A_SD = SymbolMap.lookup(A);
+
+ if (!A_SD->getFragment())
+ llvm_report_error("symbol '" + A->getName() +
+ "' can not be undefined in a subtraction expression");
+
+ uint32_t Value = A_SD->getFragment()->getAddress() + A_SD->getOffset();
uint32_t Value2 = 0;
if (const MCSymbol *B = Target.getSymB()) {
- Type = RIT_LocalDifference;
+ MCSymbolData *B_SD = SymbolMap.lookup(B);
+
+ if (!B_SD->getFragment())
+ llvm_report_error("symbol '" + B->getName() +
+ "' can not be undefined in a subtraction expression");
- MCSymbolData *SD = SymbolMap.lookup(B);
- Value2 = SD->getFragment()->getAddress() + SD->getOffset();
+ // Select the appropriate difference relocation type.
+ //
+ // Note that there is no longer any semantic difference between these two
+ // relocation types from the linkers point of view, this is done solely
+ // for pedantic compatibility with 'as'.
+ Type = A_SD->isExternal() ? RIT_Difference : RIT_LocalDifference;
+ Value2 = B_SD->getFragment()->getAddress() + B_SD->getOffset();
}
// The value which goes in the fixup is current value of the expression.
Fixup.FixedValue = Value - Value2 + Target.getConstant();
- if (isFixupKindPCRel(Fixup.Kind)) {
+ if (IsPCRel)
Fixup.FixedValue -= Address;
- IsPCRel = 1;
- }
+
+ // If this fixup is a vanilla PC relative relocation for a local label, we
+ // don't need a relocation.
+ //
+ // FIXME: Implement proper atom support.
+ if (IsPCRel && Target.getSymA() && Target.getSymA()->isTemporary() &&
+ !Target.getSymB())
+ return;
MachRelocationEntry MRE;
MRE.Word0 = ((Address << 0) |
@@ -473,14 +493,12 @@ public:
MRE.Word1 = Value;
Relocs.push_back(MRE);
- if (Type == RIT_LocalDifference) {
- Type = RIT_Pair;
-
+ if (Type == RIT_Difference || Type == RIT_LocalDifference) {
MachRelocationEntry MRE;
MRE.Word0 = ((0 << 0) |
- (Type << 24) |
+ (RIT_Pair << 24) |
(Log2Size << 28) |
- (0 << 30) |
+ (IsPCRel << 30) |
RF_Scattered);
MRE.Word1 = Value2;
Relocs.push_back(MRE);
@@ -491,15 +509,21 @@ public:
MCAsmFixup &Fixup,
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
std::vector<MachRelocationEntry> &Relocs) {
+ unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
+ unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
+
MCValue Target;
if (!Fixup.Value->EvaluateAsRelocatable(Target))
llvm_report_error("expected relocatable expression");
- // If this is a difference or a local symbol plus an offset, then we need a
- // scattered relocation entry.
+ // If this is a difference or a defined symbol plus an offset, then we need
+ // a scattered relocation entry.
+ uint32_t Offset = Target.getConstant();
+ if (IsPCRel)
+ Offset += 1 << Log2Size;
if (Target.getSymB() ||
(Target.getSymA() && !Target.getSymA()->isUndefined() &&
- Target.getConstant()))
+ Offset))
return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target,
SymbolMap, Relocs);
@@ -507,8 +531,6 @@ public:
uint32_t Address = Fragment.getOffset() + Fixup.Offset;
uint32_t Value = 0;
unsigned Index = 0;
- unsigned IsPCRel = 0;
- unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
unsigned IsExtern = 0;
unsigned Type = 0;
@@ -545,11 +567,15 @@ public:
// The value which goes in the fixup is current value of the expression.
Fixup.FixedValue = Value + Target.getConstant();
-
- if (isFixupKindPCRel(Fixup.Kind)) {
+ if (IsPCRel)
Fixup.FixedValue -= Address;
- IsPCRel = 1;
- }
+
+ // If this fixup is a vanilla PC relative relocation for a local label, we
+ // don't need a relocation.
+ //
+ // FIXME: Implement proper atom support.
+ if (IsPCRel && Target.getSymA() && Target.getSymA()->isTemporary())
+ return;
// struct relocation_info (8 bytes)
MachRelocationEntry MRE;
@@ -1040,8 +1066,8 @@ void MCAssembler::LayoutSection(MCSectionData &SD) {
// Align the fragment offset; it is safe to adjust the offset freely since
// this is only in virtual sections.
- uint64_t Aligned = RoundUpToAlignment(Address, ZFF.getAlignment());
- F.setOffset(Aligned - SD.getAddress());
+ Address = RoundUpToAlignment(Address, ZFF.getAlignment());
+ F.setOffset(Address - SD.getAddress());
// FIXME: This is misnamed.
F.setFileSize(ZFF.getSize());
@@ -1270,9 +1296,15 @@ void MCAssembler::Finish() {
if (!isVirtualSection(SD.getSection()))
continue;
+ // Align this section if necessary by adding padding bytes to the previous
+ // section.
+ if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment()))
+ Address += Pad;
+
SD.setAddress(Address);
LayoutSection(SD);
Address += SD.getSize();
+
}
DEBUG_WITH_TYPE("mc-dump", {
@@ -1336,7 +1368,7 @@ void MCDataFragment::dump() {
OS << ",\n ";
OS << " Fixups:[";
for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) {
- if (it != fixup_begin()) OS << ",\n ";
+ if (it != fixup_begin()) OS << ",\n ";
OS << *it;
}
OS << "]";
@@ -1379,7 +1411,7 @@ void MCSectionData::dump() {
OS << "<MCSectionData";
OS << " Alignment:" << getAlignment() << " Address:" << Address
<< " Size:" << Size << " FileSize:" << FileSize
- << " Fragments:[";
+ << " Fragments:[\n ";
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (it != begin()) OS << ",\n ";
it->dump();
@@ -1407,7 +1439,7 @@ void MCAssembler::dump() {
raw_ostream &OS = llvm::errs();
OS << "<MCAssembler\n";
- OS << " Sections:[";
+ OS << " Sections:[\n ";
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (it != begin()) OS << ",\n ";
it->dump();
@@ -1416,7 +1448,7 @@ void MCAssembler::dump() {
OS << " Symbols:[";
for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) {
- if (it != symbol_begin()) OS << ",\n ";
+ if (it != symbol_begin()) OS << ",\n ";
it->dump();
}
OS << "]>\n";
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index 45d2c02..63264f6 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -23,16 +23,8 @@ MCContext::~MCContext() {
// we don't need to free them here.
}
-MCSymbol *MCContext::CreateSymbol(StringRef Name) {
- assert(Name[0] != '\0' && "Normal symbols cannot be unnamed!");
-
- // Create and bind the symbol, and ensure that names are unique.
- MCSymbol *&Entry = Symbols[Name];
- assert(!Entry && "Duplicate symbol definition!");
- return Entry = new (*this) MCSymbol(Name, false);
-}
-
MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
+ assert(!Name.empty() && "Normal symbols cannot be unnamed!");
MCSymbol *&Entry = Symbols[Name];
if (Entry) return Entry;
@@ -46,17 +38,24 @@ MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
}
-MCSymbol *MCContext::CreateTemporarySymbol(StringRef Name) {
+MCSymbol *MCContext::GetOrCreateTemporarySymbol(StringRef Name) {
// If unnamed, just create a symbol.
if (Name.empty())
new (*this) MCSymbol("", true);
// Otherwise create as usual.
MCSymbol *&Entry = Symbols[Name];
- assert(!Entry && "Duplicate symbol definition!");
+ if (Entry) return Entry;
return Entry = new (*this) MCSymbol(Name, true);
}
+MCSymbol *MCContext::GetOrCreateTemporarySymbol(const Twine &Name) {
+ SmallString<128> NameSV;
+ Name.toVector(NameSV);
+ return GetOrCreateTemporarySymbol(NameSV.str());
+}
+
+
MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
return Symbols.lookup(Name);
}
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index e419043..4439eba 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -133,6 +133,11 @@ const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, MCContext &Ctx) {
return Create(Ctx.GetOrCreateSymbol(Name), Ctx);
}
+const MCSymbolRefExpr *MCSymbolRefExpr::CreateTemp(StringRef Name,
+ MCContext &Ctx) {
+ return Create(Ctx.GetOrCreateTemporarySymbol(Name), Ctx);
+}
+
void MCTargetExpr::Anchor() {}
/* *** */
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index ab61799..5f0c64a 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -29,7 +29,11 @@ namespace {
CurSection = Section;
}
- virtual void EmitLabel(MCSymbol *Symbol) {}
+ virtual void EmitLabel(MCSymbol *Symbol) {
+ assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+ assert(CurSection && "Cannot emit before setting section!");
+ Symbol->setSection(*CurSection);
+ }
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 6185c30..fc8d549 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -240,14 +240,10 @@ bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
}
MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
- if (MCSymbol *S = Ctx.LookupSymbol(Name))
- return S;
-
// If the label starts with L it is an assembler temporary label.
if (Name.startswith("L"))
- return Ctx.CreateTemporarySymbol(Name);
-
- return Ctx.CreateSymbol(Name);
+ return Ctx.GetOrCreateTemporarySymbol(Name);
+ return Ctx.GetOrCreateSymbol(Name);
}
/// ParsePrimaryExpr - Parse a primary expression and return it.
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 15b3079..703acc4 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -31,6 +31,11 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
}
+void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+ unsigned AddrSpace) {
+ EmitValue(MCSymbolRefExpr::Create(Sym, getContext()), Size, AddrSpace);
+}
+
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
OpenPOWER on IntegriCloud