diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2016-08-22 16:18:42 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2016-08-22 16:18:42 +0000 |
| commit | eb9ed6102116608b4e8cc4885eb50cedd83d57c7 (patch) | |
| tree | 0687c98a17fd68bc20bfd1cf319d6920d095c08b /llvm/lib | |
| parent | f8c2f08cb361c522f7bb614220e78bc9f77724a9 (diff) | |
| download | bcm5719-llvm-eb9ed6102116608b4e8cc4885eb50cedd83d57c7.tar.gz bcm5719-llvm-eb9ed6102116608b4e8cc4885eb50cedd83d57c7.zip | |
[mips][ias] Support .dtprel[d]word and .tprel[d]word directives
Assembler directives .dtprelword, .dtpreldword, .tprelword, and
.tpreldword generates relocations R_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL64,
R_MIPS_TLS_TPREL32, and R_MIPS_TLS_TPREL64 respectively.
The main motivation for this patch is to be able to write test cases
for checking correctness of the LLD linker's behaviour.
Differential Revision: https://reviews.llvm.org/D23669
llvm-svn: 279439
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/MC/MCAsmBackend.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 33 | ||||
| -rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 42 | ||||
| -rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 98 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 4 |
8 files changed, 207 insertions, 2 deletions
diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp index b868b9d4889..570f764f664 100644 --- a/llvm/lib/MC/MCAsmBackend.cpp +++ b/llvm/lib/MC/MCAsmBackend.cpp @@ -34,6 +34,10 @@ const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"FK_GPRel_2", 0, 16, 0}, {"FK_GPRel_4", 0, 32, 0}, {"FK_GPRel_8", 0, 64, 0}, + {"FK_DTPRel_4", 0, 32, 0}, + {"FK_DTPRel_8", 0, 64, 0}, + {"FK_TPRel_4", 0, 32, 0}, + {"FK_TPRel_8", 0, 64, 0}, {"FK_SecRel_1", 0, 8, 0}, {"FK_SecRel_2", 0, 16, 0}, {"FK_SecRel_4", 0, 32, 0}, diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index ed85f153002..c471229f39d 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -180,6 +180,11 @@ public: void EmitSLEB128Value(const MCExpr *Value) override; + void EmitDTPRel32Value(const MCExpr *Value) override; + void EmitDTPRel64Value(const MCExpr *Value) override; + void EmitTPRel32Value(const MCExpr *Value) override; + void EmitTPRel64Value(const MCExpr *Value) override; + void EmitGPRel64Value(const MCExpr *Value) override; void EmitGPRel32Value(const MCExpr *Value) override; @@ -856,6 +861,34 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) { EmitEOL(); } +void MCAsmStreamer::EmitDTPRel64Value(const MCExpr *Value) { + assert(MAI->getDTPRel64Directive() != nullptr); + OS << MAI->getDTPRel64Directive(); + Value->print(OS, MAI); + EmitEOL(); +} + +void MCAsmStreamer::EmitDTPRel32Value(const MCExpr *Value) { + assert(MAI->getDTPRel32Directive() != nullptr); + OS << MAI->getDTPRel32Directive(); + Value->print(OS, MAI); + EmitEOL(); +} + +void MCAsmStreamer::EmitTPRel64Value(const MCExpr *Value) { + assert(MAI->getTPRel64Directive() != nullptr); + OS << MAI->getTPRel64Directive(); + Value->print(OS, MAI); + EmitEOL(); +} + +void MCAsmStreamer::EmitTPRel32Value(const MCExpr *Value) { + assert(MAI->getTPRel32Directive() != nullptr); + OS << MAI->getTPRel32Directive(); + Value->print(OS, MAI); + EmitEOL(); +} + void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) { assert(MAI->getGPRel64Directive() != nullptr); OS << MAI->getGPRel64Directive(); diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index d2ac0f50261..54fb13f6918 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -445,6 +445,46 @@ void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, insert(new MCOrgFragment(*Offset, Value)); } +// Associate DTPRel32 fixup with data and resize data area +void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) { + MCDataFragment *DF = getOrCreateDataFragment(); + flushPendingLabels(DF, DF->getContents().size()); + + DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), + Value, FK_DTPRel_4)); + DF->getContents().resize(DF->getContents().size() + 4, 0); +} + +// Associate DTPRel64 fixup with data and resize data area +void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) { + MCDataFragment *DF = getOrCreateDataFragment(); + flushPendingLabels(DF, DF->getContents().size()); + + DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), + Value, FK_DTPRel_8)); + DF->getContents().resize(DF->getContents().size() + 8, 0); +} + +// Associate TPRel32 fixup with data and resize data area +void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) { + MCDataFragment *DF = getOrCreateDataFragment(); + flushPendingLabels(DF, DF->getContents().size()); + + DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), + Value, FK_TPRel_4)); + DF->getContents().resize(DF->getContents().size() + 4, 0); +} + +// Associate TPRel64 fixup with data and resize data area +void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) { + MCDataFragment *DF = getOrCreateDataFragment(); + flushPendingLabels(DF, DF->getContents().size()); + + DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), + Value, FK_TPRel_8)); + DF->getContents().resize(DF->getContents().size() + 8, 0); +} + // Associate GPRel32 fixup with data and resize data area void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); @@ -455,7 +495,7 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { DF->getContents().resize(DF->getContents().size() + 4, 0); } -// Associate GPRel32 fixup with data and resize data area +// Associate GPRel64 fixup with data and resize data area void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 6c8828f71ba..cfe25f9299c 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -127,6 +127,22 @@ void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, EmitCOFFSecRel32(Sym); } +void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) { + report_fatal_error("unsupported directive in streamer"); +} + +void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) { + report_fatal_error("unsupported directive in streamer"); +} + +void MCStreamer::EmitTPRel64Value(const MCExpr *Value) { + report_fatal_error("unsupported directive in streamer"); +} + +void MCStreamer::EmitTPRel32Value(const MCExpr *Value) { + report_fatal_error("unsupported directive in streamer"); +} + void MCStreamer::EmitGPRel64Value(const MCExpr *Value) { report_fatal_error("unsupported directive in streamer"); } diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index f6c0e0475a9..58ae3aac096 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -292,6 +292,10 @@ class MipsAsmParser : public MCTargetAsmParser { bool parseDataDirective(unsigned Size, SMLoc L); bool parseDirectiveGpWord(); bool parseDirectiveGpDWord(); + bool parseDirectiveDtpRelWord(); + bool parseDirectiveDtpRelDWord(); + bool parseDirectiveTpRelWord(); + bool parseDirectiveTpRelDWord(); bool parseDirectiveModule(); bool parseDirectiveModuleFP(); bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, @@ -5749,7 +5753,79 @@ bool MipsAsmParser::parseDirectiveGpDWord() { getParser().getStreamer().EmitGPRel64Value(Value); if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(getLexer().getLoc(), + return Error(getLexer().getLoc(), + "unexpected token, expected end of statement"); + Parser.Lex(); // Eat EndOfStatement token. + return false; +} + +/// parseDirectiveDtpRelWord +/// ::= .dtprelword tls_sym +bool MipsAsmParser::parseDirectiveDtpRelWord() { + MCAsmParser &Parser = getParser(); + const MCExpr *Value; + // EmitDTPRel32Value requires an expression, so we are using base class + // method to evaluate the expression. + if (getParser().parseExpression(Value)) + return true; + getParser().getStreamer().EmitDTPRel32Value(Value); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return Error(getLexer().getLoc(), + "unexpected token, expected end of statement"); + Parser.Lex(); // Eat EndOfStatement token. + return false; +} + +/// parseDirectiveDtpRelDWord +/// ::= .dtpreldword tls_sym +bool MipsAsmParser::parseDirectiveDtpRelDWord() { + MCAsmParser &Parser = getParser(); + const MCExpr *Value; + // EmitDTPRel64Value requires an expression, so we are using base class + // method to evaluate the expression. + if (getParser().parseExpression(Value)) + return true; + getParser().getStreamer().EmitDTPRel64Value(Value); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return Error(getLexer().getLoc(), + "unexpected token, expected end of statement"); + Parser.Lex(); // Eat EndOfStatement token. + return false; +} + +/// parseDirectiveTpRelWord +/// ::= .tprelword tls_sym +bool MipsAsmParser::parseDirectiveTpRelWord() { + MCAsmParser &Parser = getParser(); + const MCExpr *Value; + // EmitTPRel32Value requires an expression, so we are using base class + // method to evaluate the expression. + if (getParser().parseExpression(Value)) + return true; + getParser().getStreamer().EmitTPRel32Value(Value); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return Error(getLexer().getLoc(), + "unexpected token, expected end of statement"); + Parser.Lex(); // Eat EndOfStatement token. + return false; +} + +/// parseDirectiveTpRelDWord +/// ::= .tpreldword tls_sym +bool MipsAsmParser::parseDirectiveTpRelDWord() { + MCAsmParser &Parser = getParser(); + const MCExpr *Value; + // EmitTPRel64Value requires an expression, so we are using base class + // method to evaluate the expression. + if (getParser().parseExpression(Value)) + return true; + getParser().getStreamer().EmitTPRel64Value(Value); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return Error(getLexer().getLoc(), "unexpected token, expected end of statement"); Parser.Lex(); // Eat EndOfStatement token. return false; @@ -6304,6 +6380,26 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { return false; } + if (IDVal == ".dtprelword") { + parseDirectiveDtpRelWord(); + return false; + } + + if (IDVal == ".dtpreldword") { + parseDirectiveDtpRelDWord(); + return false; + } + + if (IDVal == ".tprelword") { + parseDirectiveTpRelWord(); + return false; + } + + if (IDVal == ".tpreldword") { + parseDirectiveTpRelDWord(); + return false; + } + if (IDVal == ".word") { parseDataDirective(4, DirectiveID.getLoc()); return false; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 3ee0cd9c7ec..38b11f78e36 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -59,6 +59,10 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case Mips::fixup_MIPS_PCLO16: Value &= 0xffff; break; + case FK_DTPRel_4: + case FK_DTPRel_8: + case FK_TPRel_4: + case FK_TPRel_8: case FK_GPRel_4: case FK_Data_4: case FK_Data_8: diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 47ce021cdc1..0bfd4690f47 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -270,6 +270,14 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, case Mips::fixup_Mips_64: case FK_Data_8: return ELF::R_MIPS_64; + case FK_DTPRel_4: + return ELF::R_MIPS_TLS_DTPREL32; + case FK_DTPRel_8: + return ELF::R_MIPS_TLS_DTPREL64; + case FK_TPRel_4: + return ELF::R_MIPS_TLS_TPREL32; + case FK_TPRel_8: + return ELF::R_MIPS_TLS_TPREL64; case FK_GPRel_4: if (isN64()) { unsigned Type = (unsigned)ELF::R_MIPS_NONE; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp index 2c01f919bef..5a394fe8d6b 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp @@ -45,6 +45,10 @@ MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple) { ZeroDirective = "\t.space\t"; GPRel32Directive = "\t.gpword\t"; GPRel64Directive = "\t.gpdword\t"; + DTPRel32Directive = "\t.dtprelword\t"; + DTPRel64Directive = "\t.dtpreldword\t"; + TPRel32Directive = "\t.tprelword\t"; + TPRel64Directive = "\t.tpreldword\t"; UseAssignmentForEHBegin = true; SupportsDebugInformation = true; ExceptionsType = ExceptionHandling::DwarfCFI; |

