[PATCH v2] aarch64: Add support for %dtprel(var) and R_AARCH64_TLS_DTPREL64

Shivam Gupta shivam98.tkg@gmail.com
Wed Apr 8 10:21:58 GMT 2026


On Tue, Apr 7, 2026 at 10:45 PM Alice Carlotti <alice.carlotti@arm.com>
wrote:

> On Fri, Apr 03, 2026 at 11:47:03PM +0530, Shivam Gupta wrote:
> > Hi Alice,
> >
> > This is v2 of the patch with fixes based on review comments.
> >
> > Changes in v2:
> >   - Return bfd_reloc_notsupported for SEC_ALLOC sections
> >   - Fix error handling in %dtprel parsing
> >   - Improve diagnostics
> >   - Extract operator name correctly
> >   - Remove incorrect reloc_table entry
> >   - Drop gold changes
> >   - Update test regex
> >
> > Thanks for the review!
> >
> > Shivam
>
> I think you forgot to include the commit message in this version.
>
> This is looking close to ready - I have just a few more comments below.  I
> presume you'll need someone to commit the patch for you once it's approved?
>
>
Yes, I missed that. I am not too familiar with how review works on mailing
list.
I need someone to commit the patch on my behalf.

>
> > ---
> >  bfd/elfnn-aarch64.c                     | 11 ++++++
> >  gas/config/tc-aarch64.c                 | 49 +++++++++++++++++++++++++
> >  gas/testsuite/gas/aarch64/tls-debug.d   | 10 +++++
> >  gas/testsuite/gas/aarch64/tls-debug.s   |  9 +++++
> >  ld/testsuite/ld-aarch64/aarch64-elf.exp |  1 +
> >  ld/testsuite/ld-aarch64/tls-debug.d     |  9 +++++
> >  ld/testsuite/ld-aarch64/tls-debug.s     |  9 +++++
> >  7 files changed, 98 insertions(+)
> >  create mode 100644 gas/testsuite/gas/aarch64/tls-debug.d
> >  create mode 100644 gas/testsuite/gas/aarch64/tls-debug.s
> >  create mode 100644 ld/testsuite/ld-aarch64/tls-debug.d
> >  create mode 100644 ld/testsuite/ld-aarch64/tls-debug.s
> >
> > diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
> > index 66049c81..117e1498 100644
> > --- a/bfd/elfnn-aarch64.c
> > +++ b/bfd/elfnn-aarch64.c
> > @@ -6496,6 +6496,17 @@ elfNN_aarch64_final_link_relocate
> (reloc_howto_type *howto,
> >        *unresolved_reloc_p = false;
> >        break;
> >
> > +    case BFD_RELOC_AARCH64_TLS_DTPREL:
> > +      if (input_section->flags & SEC_ALLOC)
> > +     return bfd_reloc_notsupported;
> > +      value -= dtpoff_base (info);
> > +      value += rel->r_addend;
> > +
> > +      bfd_put_64 (output_bfd, value, contents + rel->r_offset);
> > +
> > +      *unresolved_reloc_p = false;
> > +      break;
> > +
> >      case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
> >      case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
> >        if (globals->root.sgot == NULL)
> > diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> > index cd761634..66fce0be 100644
> > --- a/gas/config/tc-aarch64.c
> > +++ b/gas/config/tc-aarch64.c
> > @@ -2229,6 +2229,54 @@ s_aarch64_cons (int nbytes)
> >      {
> >        struct reloc_table_entry *reloc;
> >
> > +      /* Check for %dtprel(var) syntax */
> > +      if (*input_line_pointer == '%')
> > +     {
>
> Can we simplify these lines...
> > +       char *p = ++input_line_pointer; /* skip '%' */
> > +
> > +       /* Look for "dtprel" */
> > +       if (strncmp (p, "dtprel", 6) == 0 && p[6] == '(')
> > +         {
> > +           input_line_pointer = p + 7; /* Skip "dtprel(" */
> to
>           if (strncmp (input_line_pointer, "%dtprel(", 8) == 0)
>             {
>               input_line_pointer += 8;
>
> Thanks, I updated that in v3 of patch.

> > +
> > +           expression (&exp);
> > +
> > +           /* Ensure we have a closing parenthesis */
> > +           if (*input_line_pointer == ')')
> > +             input_line_pointer++;
> > +           else
> > +             {
> > +               as_bad (_ ("missing ')' after %%dtprel"));
> > +               ignore_rest_of_line ();
> > +               return;
> > +             }
> > +
> > +           addressT where = frag_now_fix ();
> > +           fix_new_exp (frag_now, where, nbytes, &exp, 0,
> > +                        BFD_RELOC_AARCH64_TLS_DTPREL);
> > +
> > +           char *dest = frag_more (nbytes);
> > +           memset (dest, 0, nbytes);
> > +           continue;
> > +         }
> > +
> > +       else
> > +         {
> > +           char opname[16];
> > +           char *q = p;
> > +           char *r = opname;
> > +
> > +           while (ISALPHA (*q) && r < opname + sizeof (opname) - 1)
> > +             *r++ = *q++;
> > +
> > +           *r = '\0';
> > +
> > +           as_bad (_ ("unknown relocation operator %%%s"), opname);
>
> Having looked again, I think the original error message was actually
> better,
> whereas the new error message is less accurate in some cases.  We could
> also
> avoid printing any user input (we don't bother in other similar cases),
> since
> it ought to be fairly clear from the printed error location.  So I suggest
> either:
>
>               as_bad (_("unknown relocation operator"));
>
> or:
>
>               as_bad (_("unknown relocation operator -- %s"),
>                         input_line_pointer);
>
> (note that there's no space after the underscore).
>
> Thanks, I updated that in v3 of patch.
Also I think they were introduce by clang-format -
`git clang-format  HEAD~1`.

> +           ignore_rest_of_line ();
> > +           return;
> > +         }
> > +     }
> > +
> >        expression (&exp);
> >
> >        if (exp.X_op != O_symbol)
> > @@ -10114,6 +10162,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT
> seg)
> >      case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
> >      case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
> >      case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
> > +    case BFD_RELOC_AARCH64_TLS_DTPREL:
> >        S_SET_THREAD_LOCAL (fixP->fx_addsy);
> >        /* Should always be exported to object file, see
> >        aarch64_force_relocation().  */
> > diff --git a/gas/testsuite/gas/aarch64/tls-debug.d
> b/gas/testsuite/gas/aarch64/tls-debug.d
> > new file mode 100644
> > index 00000000..1dd4df17
> > --- /dev/null
> > +++ b/gas/testsuite/gas/aarch64/tls-debug.d
> > @@ -0,0 +1,10 @@
> > +#as:
> > +#objdump: -r
> > +#target: aarch64*-*-*
> > +
> > +#...
> > +RELOCATION RECORDS FOR \[\.debug_info\]:
> > +OFFSET +TYPE +VALUE
> > +0*0 R_AARCH64_TLS_DTPREL64 +var
> > +0*8 R_AARCH64_TLS_DTPREL64 +var\+0x0+1
> > +#...
> > diff --git a/gas/testsuite/gas/aarch64/tls-debug.s
> b/gas/testsuite/gas/aarch64/tls-debug.s
> > new file mode 100644
> > index 00000000..9590ad40
> > --- /dev/null
> > +++ b/gas/testsuite/gas/aarch64/tls-debug.s
> > @@ -0,0 +1,9 @@
> > +.section .tdata,"awT",@progbits
> > +.skip 8          // Force var to have an offset of 8
> > +.globl var
> > +var:
> > +  .word 0
> > +
> > +.section        .debug_info,"",@progbits
> > +  .xword  %dtprel(var)
> > +  .xword  %dtprel(var+1)
> > diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp
> b/ld/testsuite/ld-aarch64/aarch64-elf.exp
> > index 24c73d53..fa802105 100644
> > --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
> > +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
> > @@ -261,6 +261,7 @@ run_dump_test "tls-relax-ld-le-small"
> >  run_dump_test "tls-relax-ld-le-small-ilp32"
> >  run_dump_test "tls-relax-ld-le-tiny"
> >  run_dump_test "tls-relax-ld-le-tiny-ilp32"
> > +run_dump_test "tls-debug"
> >  run_dump_test "tls-desc-ie"
> >  run_dump_test "tls-desc-ie-ilp32"
> >  run_dump_test "tls-relax-gdesc-le-2"
> > diff --git a/ld/testsuite/ld-aarch64/tls-debug.d
> b/ld/testsuite/ld-aarch64/tls-debug.d
> > new file mode 100644
> > index 00000000..4344b02e
> > --- /dev/null
> > +++ b/ld/testsuite/ld-aarch64/tls-debug.d
> > @@ -0,0 +1,9 @@
> > +#source: tls-debug.s
> > +#ld: -shared -T relocs.ld -e0
> > +#objdump: -s -j .debug_info
> > +
> > +#...
> > +Contents of section .debug_info:
> > +#...
> > + [0-9a-f]+ 08000000 00000000 09000000 00000000 .*
> > +#...
> > diff --git a/ld/testsuite/ld-aarch64/tls-debug.s
> b/ld/testsuite/ld-aarch64/tls-debug.s
> > new file mode 100644
> > index 00000000..9590ad40
> > --- /dev/null
> > +++ b/ld/testsuite/ld-aarch64/tls-debug.s
> > @@ -0,0 +1,9 @@
> > +.section .tdata,"awT",@progbits
> > +.skip 8          // Force var to have an offset of 8
> > +.globl var
> > +var:
> > +  .word 0
> > +
> > +.section        .debug_info,"",@progbits
> > +  .xword  %dtprel(var)
> > +  .xword  %dtprel(var+1)
>
> Can you include a test that uses multiple %dtprel relocations in a single
> line?
> (Adjusting your input files to combine the two lines into one looks
> sufficient
> to me.)
>
> Updated in v3 of patch.

> Alice
>
> > --
> > 2.34.1
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/binutils/attachments/20260408/b0799f02/attachment-0001.htm>


More information about the Binutils mailing list