feature. See also
. The project being documented here (as the example) is the Zig library itself.
pie.getDynamicSymbol
inline fn getDynamicSymbol() [*]const elf.Dyn
File
Code
inline fn getDynamicSymbol() [*]const elf.Dyn {
return switch (builtin.zig_backend) {
else => switch (builtin.cpu.arch) {
.x86 => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ call 1f
\\1:
\\ pop %[ret]
\\ lea _DYNAMIC - 1b(%[ret]), %[ret]
: [ret] "=r" (-> [*]const elf.Dyn),
),
.x86_64 => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ lea _DYNAMIC(%%rip), %[ret]
: [ret] "=r" (-> [*]const elf.Dyn),
),
.arc, .arceb => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ add %[ret], pcl, _DYNAMIC@pcl
: [ret] "=r" (-> [*]const elf.Dyn),
),
.arm, .armeb, .thumb, .thumbeb => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ ldr %[ret], 1f
\\ add %[ret], pc
\\ b 2f
\\1:
\\ .word _DYNAMIC-1b
\\2:
: [ret] "=r" (-> [*]const elf.Dyn),
),
.aarch64, .aarch64_be => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ adrp %[ret], _DYNAMIC
\\ add %[ret], %[ret], #:lo12:_DYNAMIC
: [ret] "=r" (-> [*]const elf.Dyn),
),
.alpha => asm volatile (
\\ br $29, 1f
\\1:
\\ ldgp $29, 0($29)
\\ ldq %[ret], -0x8000($29)
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .r26 = true, .r29 = true }),
// entry in the GOT is defined to hold the address of _DYNAMIC.
.csky => asm volatile (
\\ mov %[ret], gb
\\ ldw %[ret], %[ret]
: [ret] "=r" (-> [*]const elf.Dyn),
),
.hexagon => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ jump 1f
\\ .word _DYNAMIC - .
\\1:
\\ r1 = pc
\\ r1 = add(r1, #-4)
\\ %[ret] = memw(r1)
\\ %[ret] = add(r1, %[ret])
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .r1 = true }),
.kvx => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ pcrel %[ret] = @pcrel(_DYNAMIC)
: [ret] "=r" (-> [*]const elf.Dyn),
),
.loongarch32, .loongarch64 => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ la.local %[ret], _DYNAMIC
: [ret] "=r" (-> [*]const elf.Dyn),
),
// middle of that instruction. (The first lea is 6 bytes, the second is 4 bytes.)
.m68k => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ lea _DYNAMIC - . - 8, %[ret]
\\ lea (%[ret], %%pc), %[ret]
: [ret] "=r" (-> [*]const elf.Dyn),
),
.microblaze, .microblazeel => asm volatile (
\\ lwi %[ret], r20, 0
: [ret] "=r" (-> [*]const elf.Dyn),
),
.mips, .mipsel => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ bal 1f
\\ .gpword _DYNAMIC
\\1:
\\ lw %[ret], 0($ra)
\\ nop
\\ addu %[ret], %[ret], $gp
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .lr = true }),
.mips64, .mips64el => switch (builtin.abi) {
.gnuabin32, .muslabin32, .abin32 => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ bal 1f
\\ .gpword _DYNAMIC
\\1:
\\ lw %[ret], 0($ra)
\\ addu %[ret], %[ret], $gp
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .lr = true }),
else => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ .balign 8
\\ bal 1f
\\ .gpdword _DYNAMIC
\\1:
\\ ld %[ret], 0($ra)
\\ daddu %[ret], %[ret], $gp
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .lr = true }),
},
.or1k => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ l.jal 1f
\\ .word _DYNAMIC - .
\\1:
\\ l.lwz %[ret], 0(r9)
\\ l.add %[ret], %[ret], r9
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .r9 = true }),
.powerpc, .powerpcle => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ bl 1f
\\ .long _DYNAMIC - .
\\1:
\\ mflr %[ret]
\\ lwz 4, 0(%[ret])
\\ add %[ret], 4, %[ret]
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .lr = true, .r4 = true }),
.powerpc64, .powerpc64le => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ bl 1f
\\ .quad _DYNAMIC - .
\\1:
\\ mflr %[ret]
\\ ld 4, 0(%[ret])
\\ add %[ret], 4, %[ret]
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .lr = true, .r4 = true }),
.riscv32, .riscv32be, .riscv64, .riscv64be => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ lla %[ret], _DYNAMIC
: [ret] "=r" (-> [*]const elf.Dyn),
),
.s390x => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ larl %[ret], 1f
\\ ag %[ret], 0(%[ret])
\\ jg 2f
\\1:
\\ .quad _DYNAMIC - .
\\2:
: [ret] "=a" (-> [*]const elf.Dyn),
),
.sh, .sheb => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
\\ mova 1f, r0
\\ mov.l 1f, %[ret]
\\ add r0, %[ret]
\\ bra 2f
\\1:
\\ .balign 4
\\ .long DYNAMIC - .
\\2:
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .r0 = true }),
// to the GOT), so do it ourselves just in case.
.sparc, .sparc64 => asm volatile (
\\ sethi %%hi(_GLOBAL_OFFSET_TABLE_ - 4), %%l7
\\ call 1f
\\ add %%l7, %%lo(_GLOBAL_OFFSET_TABLE_ + 4), %%l7
\\1:
\\ add %%l7, %%o7, %[ret]
: [ret] "=r" (-> [*]const elf.Dyn),
:
: .{ .l7 = true }),
.xtensa, .xtensaeb => asm volatile (
\\ .weak _DYNAMIC
\\ .hidden _DYNAMIC
// embedded constant. Note that `call0` is a 3-byte instruction, so we need both
// `.balign` directives to be safe.
\\ .balign 4
\\ call0 1f
\\ .balign 4
\\ .word _DYNAMIC - .
\\1:
\\ add a0, a0, 1
\\ l32i a8, a0, 0
\\ add %[ret], a0, a8
: [ret] "=a" (-> [*]const elf.Dyn),
:
: .{ .a0 = true, .a8 = true }),
else => {
@compileError("PIE startup is not yet supported for this target!");
},
},
.stage2_x86_64 => @extern([*]const elf.Dyn, .{
.name = "_DYNAMIC",
.linkage = .weak,
.visibility = .hidden,
.relocation = .pcrel,
}).?,
};
}