[llvm-dev] Position independent code writes absolute pointer

Gaier, Bjoern via llvm-dev llvm-dev at lists.llvm.org
Thu Jan 9 04:20:25 PST 2020

Hello Tim,

Thank you a lot for the code! Seems like I have to learn more about the LLVM assembly to understand everything in detail.

It is still kinda sad that it is not possible to achieve the behaviour but I understand more and more why it is not possible. Thank you a lot!

Kind greetings

-----Original Message-----
From: Tim Northover <t.p.northover at gmail.com>
Sent: 09 January 2020 12:28
To: Gaier, Bjoern <Bjoern.Gaier at horiba.com>
Cc: llvm-dev at lists.llvm.org
Subject: Re: [llvm-dev] Position independent code writes absolute pointer

Hi Bjoern,

On Thu, 9 Jan 2020 at 10:34, Gaier, Bjoern <Bjoern.Gaier at horiba.com> wrote:
> > It depends how much control you have over the code. You could
> > instrument code so that it converted all stores of pointers to be
> > relative to some fixed global (PC-relative doesn't work there
> > because it will be loaded at a different address, and "relative to
> > the address it's being stored to" would break memcpy). But that has
> > some major
> This sounds interesting from a learning perspective, because I never have done something like that. Is this difficult to do? Also why only convert the stores? Shouldn't I also convert the reads so they are also valid?

Sorry, I meant to say you'd have to undo the transformation on the loads (and atomicrmw, cmpxchg) too. I think getting something that sometimes works would actually be quite easy. You'd want to make it a ModulePass to handle the globals, then you'd iterate through each function, turning a store like:

    store %type* %val, %type** %ptr


    %val.int = ptrtoint %type* %val to i64
    %val.int.new = sub i64 %val.int, ptrtoint(i8* @__GLOBAL_ANCHOR to i64)
    %val.new = inttoptr i64 %val.int.new to %type*
    store %type* %val.new, %type** %ptr

The corresponding load side would add back @__GLOBAL_ANCHOR. At the Module level you'd add some kind of tentative definition for GLOBAL_ANCHOR so it can be merged if needed, and convert a definition

    @var = global i8* @other_global


    @var = global i8* null
    define void @__MODULE_INIT() {
      ; Duplicate store code above to put a relative value for @other_global into @var
    %0 = type { i32, void ()*, i8* }
    @llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @__MODULE_INIT, i8* null }]

Unfortunately I've also thought of a couple more nasty problems while writing this out:
1. Things like target-specific vector intrinsics that do loads and stores might obscure the fact that they're storing a pointer by casting it to an i64 or something.
2. You'd have to make sure the stack for both programs as in the shared region or no-one ever used a pointer to a local variable.


Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789 Geschäftsführer: Dr. Hiroshi Nakamura, Dr. Robert Plank, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima. Junichi Tajika

More information about the llvm-dev mailing list