Commit b7db1a52 by Jan Voung

Fix --filetype=iasm non-pc-rel fixup offsets (double counted).

For pc-rel fixups, we have a ConstantRelocatable referring to Foo+0, and and the offset "-4" is encoded in the code buffer (but not the ConstantRelocatable object). Thus we need to load from the code buffer in order to get that "-4" instead of just taking the +0 from Foo+0. For non-pc-rel fixups, we have the ConstantRelocatable with a true offset, and we also write that offset into the code buffer (for ELF REL and not RELA, it expects the offset in the code buffer). In this case, we want to choose one and not double-count. BUG=none 176.gcc seemed to be failing when compiled with --filetype=iasm... load address for 64-bit pointers were +8 instead of +4 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1241313002 .
parent 87f80c12
...@@ -132,6 +132,10 @@ void Assembler::emitIASBytes(GlobalContext *Ctx) const { ...@@ -132,6 +132,10 @@ void Assembler::emitIASBytes(GlobalContext *Ctx) const {
Str << "\n"; Str << "\n";
} }
Str << "\t.long "; Str << "\t.long ";
// For PCRel fixups, we write the pc-offset from a symbol into the Buffer
// (e.g., -4), but we don't represent that in the fixup's offset.
// Otherwise the fixup holds the true offset, and so does the Buffer.
// Just load the offset from the buffer.
NextFixup->emit(Ctx, Buffer.load<RelocOffsetT>(NextFixupLoc)); NextFixup->emit(Ctx, Buffer.load<RelocOffsetT>(NextFixupLoc));
if (fixupIsPCRel(NextFixup->kind())) if (fixupIsPCRel(NextFixup->kind()))
Str << " - ."; Str << " - .";
......
...@@ -362,6 +362,8 @@ void ELFRelocationSection::writeData(const GlobalContext &Ctx, ELFStreamer &Str, ...@@ -362,6 +362,8 @@ void ELFRelocationSection::writeData(const GlobalContext &Ctx, ELFStreamer &Str,
llvm::report_fatal_error("Missing symbol mentioned in reloc"); llvm::report_fatal_error("Missing symbol mentioned in reloc");
if (IsELF64) { if (IsELF64) {
llvm_unreachable(
"Not tested -- check that Fixup.offset() is correct even for pc-rel");
Elf64_Rela Rela; Elf64_Rela Rela;
Rela.r_offset = Fixup.position(); Rela.r_offset = Fixup.position();
Rela.setSymbolAndType(Symbol->getNumber(), Fixup.kind()); Rela.setSymbolAndType(Symbol->getNumber(), Fixup.kind());
......
...@@ -48,7 +48,8 @@ IceString AssemblerFixup::symbol(const GlobalContext *Ctx) const { ...@@ -48,7 +48,8 @@ IceString AssemblerFixup::symbol(const GlobalContext *Ctx) const {
return Str.str(); return Str.str();
} }
void AssemblerFixup::emit(GlobalContext *Ctx, RelocOffsetT BaseOffset) const { void AssemblerFixup::emit(GlobalContext *Ctx,
RelocOffsetT OverrideOffset) const {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
...@@ -56,7 +57,7 @@ void AssemblerFixup::emit(GlobalContext *Ctx, RelocOffsetT BaseOffset) const { ...@@ -56,7 +57,7 @@ void AssemblerFixup::emit(GlobalContext *Ctx, RelocOffsetT BaseOffset) const {
Str << "__Sz_AbsoluteZero"; Str << "__Sz_AbsoluteZero";
else else
Str << symbol(Ctx); Str << symbol(Ctx);
RelocOffsetT Offset = offset() + BaseOffset; RelocOffsetT Offset = OverrideOffset;
if (Offset) if (Offset)
Str << " + " << Offset; Str << " + " << Offset;
} }
......
...@@ -45,7 +45,7 @@ public: ...@@ -45,7 +45,7 @@ public:
void set_value(const Constant *Value) { value_ = Value; } void set_value(const Constant *Value) { value_ = Value; }
void emit(GlobalContext *Ctx, RelocOffsetT BaseOffset) const; void emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset) const;
private: private:
intptr_t position_ = 0; intptr_t position_ = 0;
......
; Tests the integrated assembler for instructions with a reloc + offset.
; RUN: %if --need=target_X8632 --need=allow_dump \
; RUN: --command %p2i --target x8632 -i %s --args -O2 \
; RUN: | %if --need=target_X8632 --need=allow_dump --command FileCheck %s
@p_global_char = internal global [8 x i8] zeroinitializer, align 8
define internal void @reloc_in_global(i64 %x) {
entry:
%p_global_char.bc = bitcast [8 x i8]* @p_global_char to i64*
; This 64-bit load is split into an i32 store to [p_global_char]
; and an i32 store to [p_global_char + 4] on 32-bit architectures.
store i64 %x, i64* %p_global_char.bc, align 1
ret void
}
; CHECK-LABEL: reloc_in_global
; CHECK: .long p_global_char + 4
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment