title: Generating %pc relative address of constant data
body: <p>Is there a way to have gcc generate <code>%pc</code> relative addresses of constants?  Even when the string appears in the text segment, arm-elf-gcc will generate a constant pointer to the data, load the address of the pointer via a <code>%pc</code> relative address and then dereference it.  For a variety of reasons, I need to skip the middle step.  As an example, this simple function:</p>
  
  <pre><code>const char * filename(void)
  {
      static const char _filename[]
              __attribute__((section(".text")))
              = "logfile";
      return _filename;
  }
  </code></pre>
  
  <p>generates (when compiled with <code>arm-elf-gcc-4.3.2 -nostdlib -c
  -O3 -W -Wall logfile.c</code>):</p>
  
  <pre><code>00000000 &lt;filename&gt;:
     0:   e59f0000        ldr     r0, [pc, #0]    ; 8 &lt;filename+0x8&gt;
     4:   e12fff1e        bx      lr
     8:   0000000c        .word   0x0000000c
  
  0000000c &lt;_filename.1175&gt;:
     c:   66676f6c        .word   0x66676f6c
    10:   00656c69        .word   0x00656c69
  </code></pre>
  
  <p>I would have expected it to generate something more like:</p>
  
  <pre><code>filename:
      add r0, pc, #0
      bx lr
  _filename.1175:
      .ascii "logfile\000"
  </code></pre>
  
  <p>The code in question needs to be partially position independent since it will be relocated in memory at load time, but also integrate with code that was not compiled <code>-fPIC</code>, so there is no global offset table.</p>
  
  <p>My current work around is to call a non-inline function (which <i>will</i> be done via a <code>%pc</code> relative address) to find the offset from the compiled location in a technique similar to how <code>-fPIC</code> code works:</p>
  
  <pre><code>static intptr_t
  __attribute__((noinline))
  find_offset( void )
  {
      uintptr_t pc;
      asm __volatile__ (
              "mov %0, %%pc" : "=&amp;r"(pc)
      );
  
      return pc - 8 - (uintptr_t) find_offset;
  }
  </code></pre>
  
  <p>But this technique requires that <b>all</b> data references be fixed up manually, so the <code>filename()</code> function in the above example would become:</p>
  
  <pre><code>const char * filename(void)
  {
      static const char _filename[]
              __attribute__((section(".text")))
              = "logfile";
      return _filename + find_offset();
  }
  </code></pre>