Index: lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -104,8 +104,9 @@ case FK_Data_1: return 1; - case FK_Data_2: case AArch64::fixup_aarch64_movw: + case FK_Data_2: + case FK_SecRel_2: return 2; case AArch64::fixup_aarch64_pcrel_branch14: @@ -124,6 +125,7 @@ case AArch64::fixup_aarch64_pcrel_branch26: case AArch64::fixup_aarch64_pcrel_call26: case FK_Data_4: + case FK_SecRel_4: return 4; case FK_Data_8: @@ -218,6 +220,8 @@ case FK_Data_2: case FK_Data_4: case FK_Data_8: + case FK_SecRel_2: + case FK_SecRel_4: return Value; } } Index: lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp @@ -47,8 +47,49 @@ const MCFixup &Fixup, bool IsCrossSection, const MCAsmBackend &MAB) const { - const MCFixupKindInfo &Info = MAB.getFixupKindInfo(Fixup.getKind()); - report_fatal_error(Twine("unsupported relocation type: ") + Info.Name); + MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? + MCSymbolRefExpr::VK_None : + Target.getSymA()->getKind(); + + switch (static_cast(Fixup.getKind())) { + default: { + const MCFixupKindInfo &Info = MAB.getFixupKindInfo(Fixup.getKind()); + report_fatal_error(Twine("unsupported relocation type: ") + Info.Name); + } + case FK_Data_4: + switch (Modifier) { + default: + return COFF::IMAGE_REL_ARM64_ADDR32; + case MCSymbolRefExpr::VK_COFF_IMGREL32: + return COFF::IMAGE_REL_ARM64_ADDR32NB; + case MCSymbolRefExpr::VK_SECREL: + return COFF::IMAGE_REL_ARM_SECREL; + } + case FK_Data_8: + return COFF::IMAGE_REL_ARM64_ADDR64; + + case FK_SecRel_2: + return COFF::IMAGE_REL_ARM64_SECTION; + case FK_SecRel_4: + return COFF::IMAGE_REL_ARM64_SECREL; + + case AArch64::fixup_aarch64_add_imm12: + return COFF::IMAGE_REL_ARM64_PAGEOFFSET_12A; + + case AArch64::fixup_aarch64_ldst_imm12_scale1: + case AArch64::fixup_aarch64_ldst_imm12_scale2: + case AArch64::fixup_aarch64_ldst_imm12_scale4: + case AArch64::fixup_aarch64_ldst_imm12_scale8: + case AArch64::fixup_aarch64_ldst_imm12_scale16: + return COFF::IMAGE_REL_ARM64_PAGEOFFSET_12L; + + case AArch64::fixup_aarch64_pcrel_adrp_imm21: + return COFF::IMAGE_REL_ARM64_PAGEBASE_REL21; + + case AArch64::fixup_aarch64_pcrel_branch26: + case AArch64::fixup_aarch64_pcrel_call26: + return COFF::IMAGE_REL_ARM64_BRANCH26; + } } bool AArch64WinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const { Index: test/MC/AArch64/coff-relocations.ll =================================================================== --- /dev/null +++ test/MC/AArch64/coff-relocations.ll @@ -0,0 +1,106 @@ +; RUN: llc -mtriple=aarch64-windows -filetype=obj -o - %s | \ +; RUN: llvm-objdump -r - | FileCheck %s + +; CHECK: RELOCATION RECORDS FOR [.text]: +; CHECK: 0000000000000000 IMAGE_REL_ARM64_PAGEBASE_REL21 var +; CHECK: 0000000000000004 IMAGE_REL_ARM64_PAGEOFFSET_12A var +; CHECK: 0000000000000010 IMAGE_REL_ARM64_PAGEBASE_REL21 var +; CHECK: 0000000000000014 IMAGE_REL_ARM64_PAGEOFFSET_12A var +; CHECK: 0000000000000020 IMAGE_REL_ARM64_PAGEBASE_REL21 var +; CHECK: 0000000000000024 IMAGE_REL_ARM64_PAGEOFFSET_12L var + +; CHECK: RELOCATION RECORDS FOR [.data]: +; CHECK: 0000000000000000 IMAGE_REL_ARM64_ADDR64 arr + +; CHECK: RELOCATION RECORDS FOR [.debug_info]: +; CHECK: 0000000000000006 IMAGE_REL_ARM64_SECREL .debug_abbrev +; CHECK: 000000000000000c IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 0000000000000012 IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 0000000000000016 IMAGE_REL_ARM64_SECREL .debug_line +; CHECK: 000000000000001a IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 000000000000001e IMAGE_REL_ARM64_ADDR32 .text +; CHECK: 0000000000000027 IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 0000000000000033 IMAGE_REL_ARM64_ADDR32 st +; CHECK: 000000000000003c IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 000000000000004e IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 0000000000000055 IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 0000000000000061 IMAGE_REL_ARM64_ADDR32 var +; CHECK: 0000000000000066 IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 000000000000006d IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 0000000000000079 IMAGE_REL_ARM64_ADDR32 arr +; CHECK: 000000000000008a IMAGE_REL_ARM64_SECREL .debug_str +; CHECK: 0000000000000091 IMAGE_REL_ARM64_ADDR32 .text +; CHECK: 000000000000009b IMAGE_REL_ARM64_SECREL .debug_str + +; CHECK: RELOCATION RECORDS FOR [.debug_pubnames]: +; CHECK: 0000000000000006 IMAGE_REL_ARM64_SECREL .debug_info + +; CHECK: RELOCATION RECORDS FOR [.debug_pubtypes]: +; CHECK: 0000000000000006 IMAGE_REL_ARM64_SECREL .debug_info + +; CHECK: RELOCATION RECORDS FOR [.debug_line]: +; CHECK: 0000000000000027 IMAGE_REL_ARM64_ADDR32 .text + + +%struct.anon = type { i32* } + +@arr = common global [1 x i32] zeroinitializer, align 4, !dbg !0 +@st = global %struct.anon { i32* getelementptr inbounds ([1 x i32], [1 x i32]* @arr, i32 0, i32 0) }, align 8, !dbg !6 +@var = global i32 0, align 4, !dbg !13 + +; Function Attrs: noinline nounwind optnone +define i32 @func() #0 !dbg !23 { +entry: + %0 = load i32, i32* @var, align 4, !dbg !26 + %tobool = icmp ne i32 %0, 0, !dbg !26 + br i1 %tobool, label %cond.true, label %cond.false, !dbg !26 + +cond.true: ; preds = %entry + %1 = load i32, i32* @var, align 4, !dbg !27 + br label %cond.end, !dbg !26 + +cond.false: ; preds = %entry + %2 = load i32, i32* @var, align 4, !dbg !28 + %div = udiv i32 %2, 2, !dbg !29 + br label %cond.end, !dbg !26 + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %1, %cond.true ], [ %div, %cond.false ], !dbg !26 + ret i32 %cond, !dbg !30 +} + +attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+neon" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!19, !20, !21} + +!0 = !DIGlobalVariableExpression(var: !1) +!1 = distinct !DIGlobalVariable(name: "arr", scope: !2, file: !3, line: 1, type: !16, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +!3 = !DIFile(filename: "a.c", directory: "foo") +!4 = !{} +!5 = !{!6, !13, !0} +!6 = !DIGlobalVariableExpression(var: !7) +!7 = distinct !DIGlobalVariable(name: "st", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true) +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !3, line: 2, size: 64, elements: !9) +!9 = !{!10} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "mem", scope: !8, file: !3, line: 2, baseType: !11, size: 64) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DIGlobalVariableExpression(var: !14) +!14 = distinct !DIGlobalVariable(name: "var", scope: !2, file: !3, line: 4, type: !15, isLocal: false, isDefinition: true) +!15 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!16 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 32, elements: !17) +!17 = !{!18} +!18 = !DISubrange(count: 1) +!19 = !{i32 2, !"Dwarf Version", i32 4} +!20 = !{i32 2, !"Debug Info Version", i32 3} +!21 = !{i32 1, !"wchar_size", i32 2} +!23 = distinct !DISubprogram(name: "func", scope: !3, file: !3, line: 5, type: !24, isLocal: false, isDefinition: true, scopeLine: 5, isOptimized: false, unit: !2, variables: !4) +!24 = !DISubroutineType(types: !25) +!25 = !{!12} +!26 = !DILocation(line: 5, column: 21, scope: !23) +!27 = !DILocation(line: 5, column: 27, scope: !23) +!28 = !DILocation(line: 5, column: 33, scope: !23) +!29 = !DILocation(line: 5, column: 36, scope: !23) +!30 = !DILocation(line: 5, column: 14, scope: !23)