diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp --- a/bolt/lib/Core/BinaryEmitter.cpp +++ b/bolt/lib/Core/BinaryEmitter.cpp @@ -319,6 +319,14 @@ Streamer.emitCodeAlignment(Function.getAlign(), &*BC.STI); } + if (Function.size() == 0 && Function.hasIslandsInfo()) { + // If function has only constant island emit alignment before emitting + // symbols, so the emitted nops (if any) won't be part of the constant + // islands data and we would address data correctly. + const uint16_t Alignment = Function.getConstantIslandAlignment(); + Streamer.emitCodeAlignment(Align(Alignment), &*BC.STI); + } + MCContext &Context = Streamer.getContext(); const MCAsmInfo *MAI = Context.getAsmInfo(); diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -4720,9 +4720,11 @@ const uint8_t PSize = BC->AsmInfo->getCodePointerSize(); const uint64_t MaxDelta = ((CHAR_BIT * DynamicRelrEntrySize) - 1) * PSize; - auto FixAddend = [&](const BinarySection &Section, const Relocation &Rel) { + auto FixAddend = [&](const BinarySection &Section, const Relocation &Rel, + uint64_t FileOffset) { // Fix relocation symbol value in place if no static relocation found - // on the same address + // on the same address. We won't check the BF relocations here since it + // is rare case and no optimization is required. if (Section.getRelocationAt(Rel.Offset)) return; @@ -4731,11 +4733,6 @@ if (!Addend) return; - uint64_t FileOffset = Section.getOutputFileOffset(); - if (!FileOffset) - FileOffset = Section.getInputFileOffset(); - - FileOffset += Rel.Offset; OS.pwrite(reinterpret_cast(&Addend), PSize, FileOffset); }; @@ -4757,7 +4754,7 @@ RelOffset = RelOffset == 0 ? SectionAddress + Rel.Offset : RelOffset; assert((RelOffset & 1) == 0 && "Wrong relocation offset"); RelOffsets.emplace(RelOffset); - FixAddend(Section, Rel); + FixAddend(Section, Rel, RelOffset); } } diff --git a/bolt/test/AArch64/constant_island_pie_update.s b/bolt/test/AArch64/constant_island_pie_update.s --- a/bolt/test/AArch64/constant_island_pie_update.s +++ b/bolt/test/AArch64/constant_island_pie_update.s @@ -13,8 +13,11 @@ // .relr.dyn # RUN: %clang %cflags -fPIC -pie %t.o -o %t.relr.exe -nostdlib \ # RUN: -Wl,-q -Wl,-z,notext -Wl,--pack-dyn-relocs=relr +# RUN: llvm-objcopy --remove-section .rela.mytext %t.relr.exe # RUN: llvm-bolt %t.relr.exe -o %t.relr.bolt --use-old-text=0 --lite=0 # RUN: llvm-objdump -j .text -d --show-all-symbols %t.relr.bolt | FileCheck %s +# RUN: llvm-objdump -j .text -d %t.relr.bolt | \ +# RUN: FileCheck %s --check-prefix=ADDENDCHECK # RUN: llvm-readelf -rsW %t.relr.bolt | FileCheck --check-prefix=ELFCHECK %s # RUN: llvm-readelf -SW %t.relr.bolt | FileCheck --check-prefix=RELRSZCHECK %s @@ -30,6 +33,10 @@ # CHECK-NEXT: {{.*}} .word 0x{{[0]+}}[[#ADDR]] # CHECK-NEXT: {{.*}} .word 0x00000000 +// Check that addend was properly patched in mytextP with stripped relocations +# ADDENDCHECK: [[#%x,ADDR:]] : +# ADDENDCHECK: {{.*}} : +# ADDENDCHECK-NEXT: {{.*}} .word 0x{{[0]+}}[[#ADDR]] // Check that we've relaxed adr to adrp + add to refer external CI # CHECK: : @@ -40,9 +47,10 @@ # ELFCHECK: [[#%x,OFF:]] [[#%x,INFO_DYN:]] R_AARCH64_RELATIVE # ELFCHECK-NEXT: [[#OFF + 8]] {{0*}}[[#INFO_DYN]] R_AARCH64_RELATIVE # ELFCHECK-NEXT: [[#OFF + 24]] {{0*}}[[#INFO_DYN]] R_AARCH64_RELATIVE +# ELFCHECK-NEXT: {{.*}} R_AARCH64_RELATIVE # ELFCHECK: {{.*}}[[#OFF]] {{.*}} $d -// Check that .relr.dyn size is 2 bytes to ensure that last 2 relocations were +// Check that .relr.dyn size is 2 bytes to ensure that last 3 relocations were // encoded as a bitmap so the total section size for 3 relocations is 2 bytes. # RELRSZCHECK: .relr.dyn RELR [[#%x,ADDR:]] [[#%x,OFF:]] {{0*}}10 @@ -81,3 +89,17 @@ adr x1, .Lci bl _start .size addressDynCi, .-addressDynCi + + .section ".mytext", "ax" + .balign 8 + .global dummy + .type dummy, %function +dummy: + nop + .word 0 + .size dummy, .-dummy + + .global mytextP +mytextP: + .xword exitLocal + .size mytextP, .-mytextP