llvm.org GIT mirror llvm / 0d9bcaa
[PowerPC] ELFv2 MC support for .abiversion directive ELFv2 binaries are marked by a bit in the ELF header e_flags field. A new assembler directive .abiversion can be used to set that flag. This patch implements support in the PowerPC MC streamers to emit the .abiversion directive (both into assembler and ELF binary output), as well as support in the assembler parser to parse the .abiversion directive. Reviewed by Hal Finkel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213484 91177308-0d34-0410-b5e6-96231b3b80d8 Ulrich Weigand 5 years ago
5 changed file(s) with 62 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
495495 R_PPC_REL16_HA = 252
496496 };
497497
498 // Specific e_flags for PPC64
499 enum {
500 // e_flags bits specifying ABI:
501 // 1 for original ABI using function descriptors,
502 // 2 for revised ABI without function descriptors,
503 // 0 for unspecified or not using any features affected by the differences.
504 EF_PPC64_ABI = 3
505 };
506
498507 // ELF Relocation types for PPC64
499508 enum {
500509 R_PPC64_NONE = 0,
243243 bool ParseDirectiveTC(unsigned Size, SMLoc L);
244244 bool ParseDirectiveMachine(SMLoc L);
245245 bool ParseDarwinDirectiveMachine(SMLoc L);
246 bool ParseDirectiveAbiVersion(SMLoc L);
246247
247248 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
248249 OperandVector &Operands, MCStreamer &Out,
14111412 return ParseDirectiveTC(isPPC64()? 8 : 4, DirectiveID.getLoc());
14121413 if (IDVal == ".machine")
14131414 return ParseDirectiveMachine(DirectiveID.getLoc());
1415 if (IDVal == ".abiversion")
1416 return ParseDirectiveAbiVersion(DirectiveID.getLoc());
14141417 } else {
14151418 if (IDVal == ".machine")
14161419 return ParseDarwinDirectiveMachine(DirectiveID.getLoc());
15291532 Error(L, "unexpected token in directive");
15301533 return false;
15311534 }
1535
1536 return false;
1537 }
1538
1539 /// ParseDirectiveAbiVersion
1540 /// ::= .abiversion constant-expression
1541 bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) {
1542 int64_t AbiVersion;
1543 if (getParser().parseAbsoluteExpression(AbiVersion)){
1544 Error(L, "expected constant expression");
1545 return false;
1546 }
1547 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1548 Error(L, "unexpected token in directive");
1549 return false;
1550 }
1551
1552 PPCTargetStreamer &TStreamer =
1553 *static_cast(
1554 getParser().getStreamer().getTargetStreamer());
1555 TStreamer.emitAbiVersion(AbiVersion);
15321556
15331557 return false;
15341558 }
1515 #include "PPCMCAsmInfo.h"
1616 #include "PPCTargetStreamer.h"
1717 #include "llvm/MC/MCCodeGenInfo.h"
18 #include "llvm/MC/MCELFStreamer.h"
1819 #include "llvm/MC/MCInstrInfo.h"
1920 #include "llvm/MC/MCRegisterInfo.h"
2021 #include "llvm/MC/MCStreamer.h"
2122 #include "llvm/MC/MCSubtargetInfo.h"
2223 #include "llvm/MC/MCSymbol.h"
2324 #include "llvm/MC/MachineLocation.h"
25 #include "llvm/Support/ELF.h"
2426 #include "llvm/Support/ErrorHandling.h"
2527 #include "llvm/Support/FormattedStream.h"
2628 #include "llvm/Support/TargetRegistry.h"
124126 void emitMachine(StringRef CPU) override {
125127 OS << "\t.machine " << CPU << '\n';
126128 }
129 virtual void emitAbiVersion(int AbiVersion) override {
130 OS << "\t.abiversion " << AbiVersion << '\n';
131 }
127132 };
128133
129134 class PPCTargetELFStreamer : public PPCTargetStreamer {
130135 public:
131136 PPCTargetELFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {}
132 void emitTCEntry(const MCSymbol &S) override {
137 MCELFStreamer &getStreamer() {
138 return static_cast(Streamer);
139 }
140 virtual void emitTCEntry(const MCSymbol &S) override {
133141 // Creates a R_PPC64_TOC relocation
134142 Streamer.EmitSymbolValue(&S, 8);
135143 }
136144 void emitMachine(StringRef CPU) override {
137145 // FIXME: Is there anything to do in here or does this directive only
138146 // limit the parser?
147 }
148 virtual void emitAbiVersion(int AbiVersion) override {
149 MCAssembler &MCA = getStreamer().getAssembler();
150 unsigned Flags = MCA.getELFHeaderEFlags();
151 Flags &= ~ELF::EF_PPC64_ABI;
152 Flags |= (AbiVersion & ELF::EF_PPC64_ABI);
153 MCA.setELFHeaderEFlags(Flags);
139154 }
140155 };
141156
148163 void emitMachine(StringRef CPU) override {
149164 // FIXME: We should update the CPUType, CPUSubType in the Object file if
150165 // the new values are different from the defaults.
166 }
167 virtual void emitAbiVersion(int AbiVersion) override {
168 llvm_unreachable("Unknown pseudo-op: .abiversion");
151169 }
152170 };
153171 }
1818 virtual ~PPCTargetStreamer();
1919 virtual void emitTCEntry(const MCSymbol &S) = 0;
2020 virtual void emitMachine(StringRef CPU) = 0;
21 virtual void emitAbiVersion(int AbiVersion) = 0;
2122 };
2223 }
2324
0
1 # RUN: llvm-mc -triple powerpc64-unknown-unknown -filetype=obj %s | \
2 # RUN: llvm-readobj -h | FileCheck %s
3 # RUN: llvm-mc -triple powerpc64le-unknown-unknown -filetype=obj %s | \
4 # RUN: llvm-readobj -h | FileCheck %s
5
6 .abiversion 2
7 # CHECK: Flags [ (0x2)
8