Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support relocation type like RELOC_SUBTRACTOR #132

Closed
kateinoigakukun opened this issue Nov 14, 2019 · 5 comments
Closed

Support relocation type like RELOC_SUBTRACTOR #132

kateinoigakukun opened this issue Nov 14, 2019 · 5 comments

Comments

@kateinoigakukun
Copy link
Contributor

Is there any plan to support a relocate type like RELOC_SUBTRACTOR of MachO to get a difference of two addresses?

@sbc100
Copy link
Member

sbc100 commented Nov 15, 2019

It doesn't sounds impossible. Does ELF have something like this too? What is your use case? llvm seems to require the symbols to live the same section if you want relative offsets.

@kateinoigakukun
Copy link
Contributor Author

kateinoigakukun commented Nov 15, 2019

ELD has a similar feature named R_X86_64_PC32.

I'm working on supporting WebAssembly for Swift and I found there is an use case of offset calculation.

I want this feature to implement relative pointer used in Swift runtime and it's necessaryto calclulate the offset from the address of the reference to the address of its referent.

@sbc100
Copy link
Member

sbc100 commented Nov 16, 2019

R_X86_64_PC32 is for PC-relative relocations so that can't work in WebAssembly. I'm having trouble imagining the use case that swift has that we have not yet seen in other llvm languages so far. Could you perhaps post some llvm bitcode that would require such a relocation so I can better understand the use case. I'm also curious how such relocations lower in ELF because IIUC and ELF relocation only refer to single symbol (PC not really being a symbol as such).

@sbc100
Copy link
Member

sbc100 commented Nov 16, 2019

@rui314 what do you think?

@kateinoigakukun
Copy link
Contributor Author

kateinoigakukun commented Jan 6, 2020

@sbc100 For example, this swift code produce the use case.

struct Animal {}
$ swiftc -emit-ll animal.swift
; ModuleID = '-'
source_filename = "-"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

module asm ".section .swift1_autolink_entries,\220x80000000\22"

%swift.type_metadata_record = type { i32 }
%swift.type = type { i64 }
%swift.metadata_response = type { %swift.type*, i64 }

@"$sytWV" = external global i8*, align 8
@0 = private constant [7 x i8] c"animal\00"
@"$s6animalMXM" = linkonce_odr hidden constant <{ i32, i32, i32 }> <{ i32 0, i32 0, i32 trunc (i64 sub (i64 ptrtoint ([7 x i8]* @0 to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32 }>, <{ i32, i32, i32 }>* @"$s6animalMXM", i32 0, i32 2) to i64)) to i32) }>, section ".rodata", align 4
@1 = private constant [7 x i8] c"Animal\00"
@"$s6animal6AnimalVMn" = hidden constant <{ i32, i32, i32, i32, i32, i32, i32 }> <{ i32 81, i32 trunc (i64 sub (i64 ptrtoint (<{ i32, i32, i32 }>* @"$s6animalMXM" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32, i32, i32, i32 }>, <{ i32, i32, i32, i32, i32, i32, i32 }>* @"$s6animal6AnimalVMn", i32 0, i32 1) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([7 x i8]* @1 to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32, i32, i32, i32 }>, <{ i32, i32, i32, i32, i32, i32, i32 }>* @"$s6animal6AnimalVMn", i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (%swift.metadata_response (i64)* @"$s6animal6AnimalVMa" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32, i32, i32, i32 }>, <{ i32, i32, i32, i32, i32, i32, i32 }>* @"$s6animal6AnimalVMn", i32 0, i32 3) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ({ i32, i32, i16, i16, i32 }* @"$s6animal6AnimalVMF" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32, i32, i32, i32 }>, <{ i32, i32, i32, i32, i32, i32, i32 }>* @"$s6animal6AnimalVMn", i32 0, i32 4) to i64)) to i32), i32 0, i32 2 }>, section ".rodata", align 4
@"$s6animal6AnimalVMf" = internal constant <{ i8**, i64, <{ i32, i32, i32, i32, i32, i32, i32 }>* }> <{ i8** @"$sytWV", i64 512, <{ i32, i32, i32, i32, i32, i32, i32 }>* @"$s6animal6AnimalVMn" }>, align 8
@"symbolic _____ 6animal6AnimalV" = linkonce_odr hidden constant <{ i8, i32, i8 }> <{ i8 1, i32 trunc (i64 sub (i64 ptrtoint (<{ i32, i32, i32, i32, i32, i32, i32 }>* @"$s6animal6AnimalVMn" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i8, i32, i8 }>, <{ i8, i32, i8 }>* @"symbolic _____ 6animal6AnimalV", i32 0, i32 1) to i64)) to i32), i8 0 }>, section "swift5_typeref", align 2
@"$s6animal6AnimalVMF" = internal constant { i32, i32, i16, i16, i32 } { i32 trunc (i64 sub (i64 ptrtoint (<{ i8, i32, i8 }>* @"symbolic _____ 6animal6AnimalV" to i64), i64 ptrtoint ({ i32, i32, i16, i16, i32 }* @"$s6animal6AnimalVMF" to i64)) to i32), i32 0, i16 0, i16 12, i32 0 }, section "swift5_fieldmd", align 4
@"\01l_type_metadata_table" = private constant [1 x %swift.type_metadata_record] [%swift.type_metadata_record { i32 trunc (i64 sub (i64 ptrtoint (<{ i32, i32, i32, i32, i32, i32, i32 }>* @"$s6animal6AnimalVMn" to i64), i64 ptrtoint ([1 x %swift.type_metadata_record]* @"\01l_type_metadata_table" to i64)) to i32) }], section "swift5_type_metadata", align 4
@__swift_reflection_version = linkonce_odr hidden constant i16 3
@_swift1_autolink_entries = private constant [37 x i8] c"-lswiftSwiftOnoneSupport\00-lswiftCore\00", section ".swift1_autolink_entries", align 8
@llvm.used = appending global [4 x i8*] [i8* bitcast ({ i32, i32, i16, i16, i32 }* @"$s6animal6AnimalVMF" to i8*), i8* bitcast ([1 x %swift.type_metadata_record]* @"\01l_type_metadata_table" to i8*), i8* bitcast (i16* @__swift_reflection_version to i8*), i8* getelementptr inbounds ([37 x i8], [37 x i8]* @_swift1_autolink_entries, i32 0, i32 0)], section "llvm.metadata", align 8

@"$s6animal6AnimalVN" = hidden alias %swift.type, bitcast (i64* getelementptr inbounds (<{ i8**, i64, <{ i32, i32, i32, i32, i32, i32, i32 }>* }>, <{ i8**, i64, <{ i32, i32, i32, i32, i32, i32, i32 }>* }>* @"$s6animal6AnimalVMf", i32 0, i32 1) to %swift.type*)

define protected i32 @main(i32, i8**) #0 {
entry:
  %2 = bitcast i8** %1 to i8*
  ret i32 0
}

define hidden swiftcc void @"$s6animal6AnimalVACycfC"() #0 {
entry:
  ret void
}

; Function Attrs: noinline nounwind readnone
define hidden swiftcc %swift.metadata_response @"$s6animal6AnimalVMa"(i64) #1 {
entry:
  ret %swift.metadata_response { %swift.type* bitcast (i64* getelementptr inbounds (<{ i8**, i64, <{ i32, i32, i32, i32, i32, i32, i32 }>* }>, <{ i8**, i64, <{ i32, i32, i32, i32, i32, i32, i32 }>* }>* @"$s6animal6AnimalVMf", i32 0, i32 1) to %swift.type*), i64 0 }
}

attributes #0 = { "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" }
attributes #1 = { noinline nounwind readnone "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" }

!swift.module.flags = !{!0}
!llvm.asan.globals = !{!1, !2, !3, !4, !5, !6}
!llvm.linker.options = !{}
!llvm.module.flags = !{!7, !8, !9, !10}

!0 = !{!"standard-library", i1 false}
!1 = !{<{ i32, i32, i32 }>* @"$s6animalMXM", null, null, i1 false, i1 true}
!2 = !{<{ i32, i32, i32, i32, i32, i32, i32 }>* @"$s6animal6AnimalVMn", null, null, i1 false, i1 true}
!3 = !{<{ i8, i32, i8 }>* @"symbolic _____ 6animal6AnimalV", null, null, i1 false, i1 true}
!4 = !{{ i32, i32, i16, i16, i32 }* @"$s6animal6AnimalVMF", null, null, i1 false, i1 true}
!5 = !{[1 x %swift.type_metadata_record]* @"\01l_type_metadata_table", null, null, i1 false, i1 true}
!6 = !{[4 x i8*]* @llvm.used, null, null, i1 false, i1 true}
!7 = !{i32 1, !"wchar_size", i32 4}
!8 = !{i32 7, !"PIC Level", i32 2}
!9 = !{i32 4, !"Objective-C Garbage Collection", i32 83953408}
!10 = !{i32 1, !"Swift Version", i32 7}

This IR are transformed into ELF and objdump says the binary uses R_X86_64_PC32 and R_X86_64_64

$ swiftc -c animal.swift -o animal.o
$ objdump --reloc animal.o


animal.o:     file format elf64-x86-64

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE
0000000000000023 R_X86_64_PC32     .data.rel.ro+0x0000000000000004


RELOCATION RECORDS FOR [.rodata]:
OFFSET           TYPE              VALUE
0000000000000028 R_X86_64_PC32     $s6animal6AnimalVMa
000000000000002c R_X86_64_PC32     swift5_fieldmd


RELOCATION RECORDS FOR [.data.rel.ro]:
OFFSET           TYPE              VALUE
0000000000000000 R_X86_64_64       $sytWV
0000000000000010 R_X86_64_64       $s6animal6AnimalVMn


RELOCATION RECORDS FOR [swift5_typeref]:
OFFSET           TYPE              VALUE
0000000000000001 R_X86_64_PC32     $s6animal6AnimalVMn


RELOCATION RECORDS FOR [swift5_fieldmd]:
OFFSET           TYPE              VALUE
0000000000000000 R_X86_64_PC32     symbolic _____ 6animal6AnimalV


RELOCATION RECORDS FOR [swift5_type_metadata]:
OFFSET           TYPE              VALUE
0000000000000000 R_X86_64_PC32     $s6animal6AnimalVMn


RELOCATION RECORDS FOR [.eh_frame]:
OFFSET           TYPE              VALUE
0000000000000020 R_X86_64_PC32     .text
0000000000000040 R_X86_64_PC32     .text+0x0000000000000010

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants