Align IntelGOTPCRel4 with R_X86_64_GOTPCREL.

Add an addend field to reloc_external, and use it to move the
responsibility for accounting for the difference between the end of an
instruction (where the PC is considered to be in PC-relative on intel)
and the beginning of the immediate field into the encoding code.

Specifically, this makes IntelGOTPCRel4 directly correspond to
R_X86_64_GOTPCREL, instead of also carrying an implicit `- 4`.
This commit is contained in:
Dan Gohman
2017-12-14 07:13:17 -06:00
parent 76e31cc1ad
commit 4f53cc1dad
7 changed files with 66 additions and 26 deletions

View File

@@ -30,11 +30,11 @@ ebb0:
call fn0() ; bin: e8 PLTRel4(%foo) 00000000
; asm: mov 0x0(%rip), %rax
[-,%rax] v0 = func_addr.i64 fn0 ; bin: 48 8b 05 GOTPCRel4(%foo) 00000000
[-,%rax] v0 = func_addr.i64 fn0 ; bin: 48 8b 05 GOTPCRel4(%foo-4) 00000000
; asm: mov 0x0(%rip), %rsi
[-,%rsi] v1 = func_addr.i64 fn0 ; bin: 48 8b 35 GOTPCRel4(%foo) 00000000
[-,%rsi] v1 = func_addr.i64 fn0 ; bin: 48 8b 35 GOTPCRel4(%foo-4) 00000000
; asm: mov 0x0(%rip), %r10
[-,%r10] v2 = func_addr.i64 fn0 ; bin: 4c 8b 15 GOTPCRel4(%foo) 00000000
[-,%r10] v2 = func_addr.i64 fn0 ; bin: 4c 8b 15 GOTPCRel4(%foo-4) 00000000
; asm: call *%rax
call_indirect sig0, v0() ; bin: ff d0
@@ -44,11 +44,11 @@ ebb0:
call_indirect sig0, v2() ; bin: 41 ff d2
; asm: mov 0x0(%rip), %rcx
[-,%rcx] v3 = globalsym_addr.i64 gv0 ; bin: 48 8b 0d GOTPCRel4(%some_gv) 00000000
[-,%rcx] v3 = globalsym_addr.i64 gv0 ; bin: 48 8b 0d GOTPCRel4(%some_gv-4) 00000000
; asm: mov 0x0(%rip), %rsi
[-,%rsi] v4 = globalsym_addr.i64 gv0 ; bin: 48 8b 35 GOTPCRel4(%some_gv) 00000000
[-,%rsi] v4 = globalsym_addr.i64 gv0 ; bin: 48 8b 35 GOTPCRel4(%some_gv-4) 00000000
; asm: mov 0x0(%rip), %r10
[-,%r10] v5 = globalsym_addr.i64 gv0 ; bin: 4c 8b 15 GOTPCRel4(%some_gv) 00000000
[-,%r10] v5 = globalsym_addr.i64 gv0 ; bin: 4c 8b 15 GOTPCRel4(%some_gv-4) 00000000
return
}

View File

@@ -72,13 +72,29 @@ impl binemit::CodeSink for TextSink {
write!(self.text, "{}({}) ", reloc, ebb_offset).unwrap();
}
fn reloc_external(&mut self, reloc: binemit::Reloc, name: &ir::ExternalName) {
fn reloc_external(
&mut self,
reloc: binemit::Reloc,
name: &ir::ExternalName,
addend: binemit::Addend,
) {
write!(
self.text,
"{}({}) ",
"{}({}",
reloc,
name,
).unwrap();
if addend != 0 {
write!(
self.text,
"{:+}",
addend,
).unwrap();
}
write!(
self.text,
") ",
).unwrap();
}
fn reloc_jt(&mut self, reloc: binemit::Reloc, jt: ir::JumpTable) {

View File

@@ -103,6 +103,12 @@ impl binemit::CodeSink for SizeSink {
}
fn reloc_ebb(&mut self, _reloc: binemit::Reloc, _ebb_offset: binemit::CodeOffset) {}
fn reloc_external(&mut self, _reloc: binemit::Reloc, _name: &ir::ExternalName) {}
fn reloc_external(
&mut self,
_reloc: binemit::Reloc,
_name: &ir::ExternalName,
_addend: binemit::Addend,
) {
}
fn reloc_jt(&mut self, _reloc: binemit::Reloc, _jt: ir::JumpTable) {}
}