#include "VEFixupKinds.h"
#include "VEMCExpr.h"
#include "VEMCTargetDesc.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
if (IsPCRel) {
switch (Fixup.getTargetKind()) {
default:
- llvm_unreachable("Unimplemented fixup -> relocation");
+ Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind");
+ return ELF::R_VE_NONE;
+ case FK_Data_1:
case FK_PCRel_1:
- llvm_unreachable("Unimplemented fixup fk_data_1 -> relocation");
+ Ctx.reportError(Fixup.getLoc(),
+ "1-byte pc-relative data relocation is not supported");
+ return ELF::R_VE_NONE;
+ case FK_Data_2:
case FK_PCRel_2:
- llvm_unreachable("Unimplemented fixup fk_data_2 -> relocation");
- // FIXME: relative kind?
+ Ctx.reportError(Fixup.getLoc(),
+ "2-byte pc-relative data relocation is not supported");
+ return ELF::R_VE_NONE;
+ case FK_Data_4:
case FK_PCRel_4:
- return ELF::R_VE_REFLONG;
+ return ELF::R_VE_SREL32;
+ case FK_Data_8:
case FK_PCRel_8:
- return ELF::R_VE_REFQUAD;
+ Ctx.reportError(Fixup.getLoc(),
+ "8-byte pc-relative data relocation is not supported");
+ return ELF::R_VE_NONE;
case VE::fixup_ve_srel32:
return ELF::R_VE_SREL32;
case VE::fixup_ve_pc_hi32:
switch (Fixup.getTargetKind()) {
default:
- llvm_unreachable("Unimplemented fixup -> relocation");
+ Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type");
+ return ELF::R_VE_NONE;
case FK_Data_1:
- llvm_unreachable("Unimplemented fixup fk_data_1 -> relocation");
+ Ctx.reportError(Fixup.getLoc(), "1-byte data relocation is not supported");
+ return ELF::R_VE_NONE;
case FK_Data_2:
- llvm_unreachable("Unimplemented fixup fk_data_2 -> relocation");
+ Ctx.reportError(Fixup.getLoc(), "2-byte data relocation is not supported");
+ return ELF::R_VE_NONE;
case FK_Data_4:
return ELF::R_VE_REFLONG;
case FK_Data_8:
case VE::fixup_ve_reflong:
return ELF::R_VE_REFLONG;
case VE::fixup_ve_srel32:
- llvm_unreachable("Unimplemented fixup pc_hi32 -> relocation");
+ Ctx.reportError(Fixup.getLoc(),
+ "A non pc-relative srel32 relocation is not supported");
+ return ELF::R_VE_NONE;
case VE::fixup_ve_hi32:
return ELF::R_VE_HI32;
case VE::fixup_ve_lo32:
return ELF::R_VE_LO32;
case VE::fixup_ve_pc_hi32:
- llvm_unreachable("Unimplemented fixup pc_hi32 -> relocation");
+ Ctx.reportError(Fixup.getLoc(),
+ "A non pc-relative pc_hi32 relocation is not supported");
+ return ELF::R_VE_NONE;
case VE::fixup_ve_pc_lo32:
- llvm_unreachable("Unimplemented fixup pc_lo32 -> relocation");
+ Ctx.reportError(Fixup.getLoc(),
+ "A non pc-relative pc_lo32 relocation is not supported");
+ return ELF::R_VE_NONE;
case VE::fixup_ve_got_hi32:
return ELF::R_VE_GOT_HI32;
case VE::fixup_ve_got_lo32:
const MCSubtargetInfo &STI) const {
if (MO.isReg())
return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
-
if (MO.isImm())
- return MO.getImm();
+ return static_cast<unsigned>(MO.getImm());
assert(MO.isExpr());
+
const MCExpr *Expr = MO.getExpr();
if (const VEMCExpr *SExpr = dyn_cast<VEMCExpr>(Expr)) {
MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
//===----------------------------------------------------------------------===//
#include "VEMCExpr.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSymbolELF.h"
-#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/MCValue.h"
using namespace llvm;
bool VEMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout,
const MCFixup *Fixup) const {
- return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
+ if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup))
+ return false;
+
+ Res =
+ MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
+
+ return true;
}
static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
--- /dev/null
+# RUN: not llvm-mc -filetype=obj -triple=ve %s -o /dev/null 2>&1 | \
+# RUN: FileCheck %s
+# RUN: not llvm-mc -filetype=obj -triple=ve -position-independent %s \
+# RUN: -o /dev/null 2>&1 | FileCheck %s
+
+.data
+a:
+## An undefined reference of _GLOBAL_OFFSET_TABLE_ causes .got[0] to be
+## allocated to store _DYNAMIC.
+.byte _GLOBAL_OFFSET_TABLE_
+.byte _GLOBAL_OFFSET_TABLE_ - .
+.2byte _GLOBAL_OFFSET_TABLE_
+.2byte _GLOBAL_OFFSET_TABLE_ - .
+.8byte _GLOBAL_OFFSET_TABLE_ - .
+
+# CHECK: data-reloc-error.s:10:7: error: 1-byte data relocation is not supported
+# CHECK-NEXT: .byte _GLOBAL_OFFSET_TABLE_
+# CHECK: data-reloc-error.s:11:7: error: 1-byte pc-relative data relocation is not supported
+# CHECK-NEXT: .byte _GLOBAL_OFFSET_TABLE_ - .
+# CHECK: data-reloc-error.s:12:8: error: 2-byte data relocation is not supported
+# CHECK-NEXT: .2byte _GLOBAL_OFFSET_TABLE_
+# CHECK: data-reloc-error.s:13:8: error: 2-byte pc-relative data relocation is not supported
+# CHECK-NEXT: .2byte _GLOBAL_OFFSET_TABLE_ - .
+# CHECK: data-reloc-error.s:14:8: error: 8-byte pc-relative data relocation is not supported
+# CHECK-NEXT: .8byte _GLOBAL_OFFSET_TABLE_ - .
+
--- /dev/null
+# RUN: llvm-mc -triple=ve -filetype=obj %s -o - | \
+# RUN: llvm-objdump -r - | FileCheck %s
+# RUN: llvm-mc -triple=ve -filetype=obj -position-independent %s -o - | \
+# RUN: llvm-objdump -r - | FileCheck %s
+
+.data
+a:
+## An undefined reference of _GLOBAL_OFFSET_TABLE_ causes .got[0] to be
+## allocated to store _DYNAMIC.
+.4byte _GLOBAL_OFFSET_TABLE_ - 8
+.4byte _GLOBAL_OFFSET_TABLE_ - . - 8
+.8byte _GLOBAL_OFFSET_TABLE_ - 8
+
+# CHECK: 0000000000000000 R_VE_REFLONG _GLOBAL_OFFSET_TABLE_-0x8
+# CHECK: 0000000000000004 R_VE_SREL32 _GLOBAL_OFFSET_TABLE_-0x8
+# CHECK: 0000000000000008 R_VE_REFQUAD _GLOBAL_OFFSET_TABLE_-0x8