Skip to content

Commit

Permalink
[COFF] Add support for the .secidx directive
Browse files Browse the repository at this point in the history
Reviewed at http://llvm-reviews.chandlerc.com/D2445

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197826 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
timurrrr committed Dec 20, 2013
1 parent fc90ff9 commit 8aa3ff0
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 3 deletions.
18 changes: 17 additions & 1 deletion docs/Extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ X86/COFF-Dependent
Relocations
^^^^^^^^^^^

The following additional relocation type is supported:
The following additional relocation types are supported:

**@IMGREL** (AT&T syntax only) generates an image-relative relocation that
corresponds to the COFF relocation types ``IMAGE_REL_I386_DIR32NB`` (32-bit) or
Expand All @@ -54,6 +54,22 @@ corresponds to the COFF relocation types ``IMAGE_REL_I386_DIR32NB`` (32-bit) or
.long (fun@imgrel + 0x3F)
.long $unwind$fun@imgrel
**.secrel32** generates a relocation that corresponds to the COFF relocation
types ``IMAGE_REL_I386_SECREL`` (32-bit) or ``IMAGE_REL_AMD64_SECREL`` (64-bit).

**.secidx** relocation generates an index of the section that contains
the target. It corresponds to the COFF relocation types
``IMAGE_REL_I386_SECTION`` (32-bit) or ``IMAGE_REL_AMD64_SECTION`` (64-bit).

.. code-block:: gas
.section .debug$S,"rn"
.long 4
.long 242
.long 40
.secrel32 _function_name
.secidx _function_name
...
``.linkonce`` Directive
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
5 changes: 5 additions & 0 deletions include/llvm/MC/MCStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,11 @@ class MCStreamer {
/// EndCOFFSymbolDef - Marks the end of the symbol definition.
virtual void EndCOFFSymbolDef() = 0;

/// EmitCOFFSectionIndex - Emits a COFF section index.
///
/// @param Symbol - Symbol the section number relocation should point to.
virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);

/// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
///
/// @param Symbol - Symbol the section relative relocation should point to.
Expand Down
8 changes: 7 additions & 1 deletion lib/MC/MCAsmStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class MCAsmStreamer : public MCStreamer {
virtual void EmitCOFFSymbolStorageClass(int StorageClass);
virtual void EmitCOFFSymbolType(int Type);
virtual void EndCOFFSymbolDef();
virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);
virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Expand Down Expand Up @@ -505,8 +506,13 @@ void MCAsmStreamer::EndCOFFSymbolDef() {
EmitEOL();
}

void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
OS << "\t.secidx\t" << *Symbol;
EmitEOL();
}

void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
OS << "\t.secrel32\t" << *Symbol << '\n';
OS << "\t.secrel32\t" << *Symbol;
EmitEOL();
}

Expand Down
19 changes: 18 additions & 1 deletion lib/MC/MCParser/COFFAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class COFFAsmParser : public MCAsmParserExtension {
addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");

// Win64 EH directives.
Expand Down Expand Up @@ -115,6 +116,7 @@ class COFFAsmParser : public MCAsmParserExtension {
bool ParseDirectiveType(StringRef, SMLoc);
bool ParseDirectiveEndef(StringRef, SMLoc);
bool ParseDirectiveSecRel32(StringRef, SMLoc);
bool ParseDirectiveSecIdx(StringRef, SMLoc);
bool parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
const MCSectionCOFF *&Assoc);
bool ParseDirectiveLinkOnce(StringRef, SMLoc);
Expand Down Expand Up @@ -432,7 +434,7 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
return true;
return TokError("expected identifier in directive");

if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
Expand All @@ -444,6 +446,21 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
return false;
}

bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
return TokError("expected identifier in directive");

if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");

MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);

Lex();
getStreamer().EmitCOFFSectionIndex(Symbol);
return false;
}

/// ::= [ identifier [ identifier ] ]
bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
const MCSectionCOFF *&Assoc) {
Expand Down
4 changes: 4 additions & 0 deletions lib/MC/MCStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,10 @@ void MCStreamer::EmitWin64EHEndProlog() {
EmitLabel(CurFrame->PrologEnd);
}

void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
llvm_unreachable("This file format doesn't support this directive");
}

void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
llvm_unreachable("This file format doesn't support this directive");
}
Expand Down
12 changes: 12 additions & 0 deletions lib/MC/WinCOFFStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class WinCOFFStreamer : public MCObjectStreamer {
virtual void EmitCOFFSymbolStorageClass(int StorageClass);
virtual void EmitCOFFSymbolType(int Type);
virtual void EndCOFFSymbolDef();
virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);
virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Expand Down Expand Up @@ -249,6 +250,17 @@ void WinCOFFStreamer::EndCOFFSymbolDef() {
CurSymbol = NULL;
}

void WinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol)
{
MCDataFragment *DF = getOrCreateDataFragment();

DF->getFixups().push_back(
MCFixup::Create(DF->getContents().size(),
MCSymbolRefExpr::Create (Symbol, getContext ()),
FK_SecRel_2));
DF->getContents().resize(DF->getContents().size() + 4, 0);
}

void WinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol)
{
MCDataFragment *DF = getOrCreateDataFragment();
Expand Down
3 changes: 3 additions & 0 deletions lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ unsigned X86WinCOFFObjectWriter::getRelocType(const MCValue &Target,
if (Is64Bit)
return COFF::IMAGE_REL_AMD64_ADDR64;
llvm_unreachable("unsupported relocation type");
case FK_SecRel_2:
return Is64Bit ? COFF::IMAGE_REL_AMD64_SECTION
: COFF::IMAGE_REL_I386_SECTION;
case FK_SecRel_4:
return Is64Bit ? COFF::IMAGE_REL_AMD64_SECREL : COFF::IMAGE_REL_I386_SECREL;
default:
Expand Down

0 comments on commit 8aa3ff0

Please sign in to comment.