aix: implement TLS relocation for gas and ld
Add support for TLS in XCOFF. Amongst the things done by this commit: - Update XCOFF auxialiary header to match new version and allow TLS sections. - Add TLS sections (.tdata and .tbss) support in gas and ld. - Add support for the TLS relocations in gas and ld. Two different types BFD_RELOC are created for PPC and PPC64 as the size is a pointer, thus distinct in 32 or 64bit. The addresses given by ld to .tdata and .tbss is a bit special. In XCOFF, these addresses are actually offsets from the TLS pointer computed at runtime. AIX assembly and linker does the same. In top of that, the .tdata must be before .data (this is mandatory for AIX loader). Thus, the aix ld script is recomputing "." before .data to restore its original value. There might be a simpler way, but this one is working. Optimisation linked to TLS relocations aren't yet implemented. bfd/ * reloc.c (BFD_RELOC_PPC_TLS_LE, BFD_RELOC_PPC_TLS_IE, BFD_RELOC_PPC_TLS_M, BFD_RELOC_PPC_TLS_ML, BFD_RELOC_PPC64_TLS_GD, BFD_RELOC_PPC64_TLS_LD, BFD_RELOC_PPC64_TLS_LE, BFD_RELOC_PPC64_TLS_IE, BFD_RELOC_PPC64_TLS_M, BFD_RELOC_PPC64_TLS_ML): New relocations. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. * coff-rs6000.c (xcoff_calculate_relocation): Call xcoff_reloc_type_tls for TLS relocations. (xcoff_howto_table): Implement TLS relocations. (_bfd_xcoff_reloc_type_lookup): Add cases TLS relocations. (xcoff_reloc_type_tls): New function. * coff64-rs6000.c (xcoff_calculate_relocation): Likewise. (xcoff_howto_table): Likewise. (_bfd_xcoff_reloc_type_lookup): Likewise. * coffcode.h (sec_to_styp_flags): Handle TLS sections. (styp_to_sec_flags): Likewise. (coff_compute_section_file_positions): Avoid file offset optimisation for .data when the previous section is .tdata. (coff_write_object_contents): Handle TLS sections. * coffswap.h (coff_swap_aouthdr_out): Add support for new fields in aouthdr. * libxcoff.h (xcoff_reloc_type_tls): Add prototype. * xcofflink.c (xcoff_link_add_symbols): Handle XMC_UL. (xcoff_need_ldrel_p): Add cases for TLS relocations. (xcoff_create_ldrel): Add l_symndx for TLS sections. gas/ * config/tc-ppc.c (ppc_xcoff_text_section, ppc_xcoff_data_section, (ppc_xcoff_bss_section, ppc_xcoff_tdata_section, (ppc_xcoff_tbss_section): New variables. (ppc_text_subsegment, ppc_text_csects, ppc_data_subgments, (ppc_data_csects): Removed. (ppc_xcoff_section_is_initialized, ppc_init_xcoff_section, ppc_xcoff_parse_cons): New functions. (md_being): Initialize XCOFF sections. (ppc_xcoff_suffix): Add support for TLS relocations (fixup_size, md_apply_fix): Add support for new BFD_RELOC. (ppc_change_csect): Handle XMC_TL, XMC_UL. Correctly, add XMC_BS to .bss section. Handle new XCOFF section variables. (ppc_comm): Likewise. (ppc_toc): Likewise. (ppc_symbol_new_hook): Likewise. (ppc_frob_symbol): Likewise. (ppc_fix_adjustable): Add tbss support. * config/tc-ppc.h (TC_PARSE_CONS_EXPRESSION): New define. (ppc_xcoff_parse_cons): Add prototype. (struct ppc_xcoff_section): New structure. ld/ * emultempl/aix.em: Ensure .tdata section is removed if empty, even with -r flag. * scripttempl/aix.sc: Handle TLS sections. * testsuite/ld-powerpc/aix52.exp: Add new tests. * testsuite/ld-powerpc/aix-tls-reloc-32.d: New test. * testsuite/ld-powerpc/aix-tls-reloc-64.d: New test. * testsuite/ld-powerpc/aix-tls-reloc.ex: New test. * testsuite/ld-powerpc/aix-tls-reloc.s: New test. * testsuite/ld-powerpc/aix-tls-section-32.d: New test. * testsuite/ld-powerpc/aix-tls-section-64.d: New test. * testsuite/ld-powerpc/aix-tls-section.ex: New test. * testsuite/ld-powerpc/aix-tls-section.s: New test. include/ * coff/internal.h (struct internal_aouthdr): Add new fields. * coff/rs6000.h (AOUTHDRÃ): Add new fields. * coff/rs6k64.h (struct external_filehdr): Likewise. * coff/xcoff.h (_TDATA), _TBSS): New defines (RS6K_AOUTHDR_TLS_LE, RS6K_AOUTHDR_RAS, RS6K_AOUTHDR_ALGNTDATA, RS6K_AOUTHDR_SHR_SYMTAB, RS6K_AOUTHDR_FORK_POLICY, RS6K_AOUTHDR_FORK_COR): New defines. (XMC_TU): Removed. (XMC_UL): New define.
This commit is contained in:
parent
4a403be0c1
commit
1b2cb8e2ee
@ -1,3 +1,32 @@
|
|||||||
|
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||||
|
|
||||||
|
* reloc.c (BFD_RELOC_PPC_TLS_LE, BFD_RELOC_PPC_TLS_IE,
|
||||||
|
BFD_RELOC_PPC_TLS_M, BFD_RELOC_PPC_TLS_ML, BFD_RELOC_PPC64_TLS_GD,
|
||||||
|
BFD_RELOC_PPC64_TLS_LD, BFD_RELOC_PPC64_TLS_LE,
|
||||||
|
BFD_RELOC_PPC64_TLS_IE, BFD_RELOC_PPC64_TLS_M,
|
||||||
|
BFD_RELOC_PPC64_TLS_ML): New relocations.
|
||||||
|
* bfd-in2.h: Regenerate.
|
||||||
|
* libbfd.h: Regenerate.
|
||||||
|
* coff-rs6000.c (xcoff_calculate_relocation): Call
|
||||||
|
xcoff_reloc_type_tls for TLS relocations.
|
||||||
|
(xcoff_howto_table): Implement TLS relocations.
|
||||||
|
(_bfd_xcoff_reloc_type_lookup): Add cases TLS relocations.
|
||||||
|
(xcoff_reloc_type_tls): New function.
|
||||||
|
* coff64-rs6000.c (xcoff_calculate_relocation): Likewise.
|
||||||
|
(xcoff_howto_table): Likewise.
|
||||||
|
(_bfd_xcoff_reloc_type_lookup): Likewise.
|
||||||
|
* coffcode.h (sec_to_styp_flags): Handle TLS sections.
|
||||||
|
(styp_to_sec_flags): Likewise.
|
||||||
|
(coff_compute_section_file_positions): Avoid file offset
|
||||||
|
optimisation for .data when the previous section is .tdata.
|
||||||
|
(coff_write_object_contents): Handle TLS sections.
|
||||||
|
* coffswap.h (coff_swap_aouthdr_out): Add support for
|
||||||
|
new fields in aouthdr.
|
||||||
|
* libxcoff.h (xcoff_reloc_type_tls): Add prototype.
|
||||||
|
* xcofflink.c (xcoff_link_add_symbols): Handle XMC_UL.
|
||||||
|
(xcoff_need_ldrel_p): Add cases for TLS relocations.
|
||||||
|
(xcoff_create_ldrel): Add l_symndx for TLS sections.
|
||||||
|
|
||||||
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||||
|
|
||||||
* reloc.c (BFD_RELOC_PPC_TOC16_HI, BFD_RELOC_PPC_TOC16_LO):
|
* reloc.c (BFD_RELOC_PPC_TOC16_HI, BFD_RELOC_PPC_TOC16_LO):
|
||||||
|
@ -3003,6 +3003,10 @@ instruction. */
|
|||||||
BFD_RELOC_PPC_TLS,
|
BFD_RELOC_PPC_TLS,
|
||||||
BFD_RELOC_PPC_TLSGD,
|
BFD_RELOC_PPC_TLSGD,
|
||||||
BFD_RELOC_PPC_TLSLD,
|
BFD_RELOC_PPC_TLSLD,
|
||||||
|
BFD_RELOC_PPC_TLSLE,
|
||||||
|
BFD_RELOC_PPC_TLSIE,
|
||||||
|
BFD_RELOC_PPC_TLSM,
|
||||||
|
BFD_RELOC_PPC_TLSML,
|
||||||
BFD_RELOC_PPC_DTPMOD,
|
BFD_RELOC_PPC_DTPMOD,
|
||||||
BFD_RELOC_PPC_TPREL16,
|
BFD_RELOC_PPC_TPREL16,
|
||||||
BFD_RELOC_PPC_TPREL16_LO,
|
BFD_RELOC_PPC_TPREL16_LO,
|
||||||
@ -3030,6 +3034,12 @@ instruction. */
|
|||||||
BFD_RELOC_PPC_GOT_DTPREL16_LO,
|
BFD_RELOC_PPC_GOT_DTPREL16_LO,
|
||||||
BFD_RELOC_PPC_GOT_DTPREL16_HI,
|
BFD_RELOC_PPC_GOT_DTPREL16_HI,
|
||||||
BFD_RELOC_PPC_GOT_DTPREL16_HA,
|
BFD_RELOC_PPC_GOT_DTPREL16_HA,
|
||||||
|
BFD_RELOC_PPC64_TLSGD,
|
||||||
|
BFD_RELOC_PPC64_TLSLD,
|
||||||
|
BFD_RELOC_PPC64_TLSLE,
|
||||||
|
BFD_RELOC_PPC64_TLSIE,
|
||||||
|
BFD_RELOC_PPC64_TLSM,
|
||||||
|
BFD_RELOC_PPC64_TLSML,
|
||||||
BFD_RELOC_PPC64_TPREL16_DS,
|
BFD_RELOC_PPC64_TPREL16_DS,
|
||||||
BFD_RELOC_PPC64_TPREL16_LO_DS,
|
BFD_RELOC_PPC64_TPREL16_LO_DS,
|
||||||
BFD_RELOC_PPC64_TPREL16_HIGH,
|
BFD_RELOC_PPC64_TPREL16_HIGH,
|
||||||
|
@ -190,12 +190,12 @@ xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] =
|
|||||||
xcoff_reloc_type_fail, /* (0x1d) */
|
xcoff_reloc_type_fail, /* (0x1d) */
|
||||||
xcoff_reloc_type_fail, /* (0x1e) */
|
xcoff_reloc_type_fail, /* (0x1e) */
|
||||||
xcoff_reloc_type_fail, /* (0x1f) */
|
xcoff_reloc_type_fail, /* (0x1f) */
|
||||||
xcoff_reloc_type_fail, /* R_TLS (0x20) */
|
xcoff_reloc_type_tls, /* R_TLS (0x20) */
|
||||||
xcoff_reloc_type_fail, /* R_TLS_IE (0x21) */
|
xcoff_reloc_type_tls, /* R_TLS_IE (0x21) */
|
||||||
xcoff_reloc_type_fail, /* R_TLS_LD (0x22) */
|
xcoff_reloc_type_tls, /* R_TLS_LD (0x22) */
|
||||||
xcoff_reloc_type_fail, /* R_TLS_LE (0x23) */
|
xcoff_reloc_type_tls, /* R_TLS_LE (0x23) */
|
||||||
xcoff_reloc_type_fail, /* R_TLSM (0x24) */
|
xcoff_reloc_type_tls, /* R_TLSM (0x24) */
|
||||||
xcoff_reloc_type_fail, /* R_TLSML (0x25) */
|
xcoff_reloc_type_tls, /* R_TLSML (0x25) */
|
||||||
xcoff_reloc_type_fail, /* (0x26) */
|
xcoff_reloc_type_fail, /* (0x26) */
|
||||||
xcoff_reloc_type_fail, /* (0x27) */
|
xcoff_reloc_type_fail, /* (0x27) */
|
||||||
xcoff_reloc_type_fail, /* (0x28) */
|
xcoff_reloc_type_fail, /* (0x28) */
|
||||||
@ -1064,22 +1064,95 @@ reloc_howto_type xcoff_howto_table[] =
|
|||||||
EMPTY_HOWTO (0x1f),
|
EMPTY_HOWTO (0x1f),
|
||||||
|
|
||||||
/* 0x20: General-dynamic TLS relocation. */
|
/* 0x20: General-dynamic TLS relocation. */
|
||||||
EMPTY_HOWTO (R_TLS),
|
HOWTO (R_TLS, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
32, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLS", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
0xffffffff, /* src_mask */
|
||||||
|
0xffffffff, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* 0x21: Initial-exec TLS relocation. */
|
/* 0x21: Initial-exec TLS relocation. */
|
||||||
EMPTY_HOWTO (R_TLS_IE),
|
HOWTO (R_TLS_IE, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
32, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLS_IE", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
0xffffffff, /* src_mask */
|
||||||
|
0xffffffff, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* 0x22: Local-dynamic TLS relocation. */
|
/* 0x22: Local-dynamic TLS relocation. */
|
||||||
EMPTY_HOWTO (R_TLS_LD),
|
HOWTO (R_TLS_LD, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
32, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLS_LD", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
0xffffffff, /* src_mask */
|
||||||
|
0xffffffff, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* 0x23: Local-exec TLS relocation. */
|
/* 0x23: Local-exec TLS relocation. */
|
||||||
EMPTY_HOWTO (R_TLS_LE),
|
HOWTO (R_TLS_LE, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
32, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLS_LE", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
0xffffffff, /* src_mask */
|
||||||
|
0xffffffff, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* 0x24: TLS relocation. */
|
/* 0x24: TLS relocation. */
|
||||||
EMPTY_HOWTO(R_TLSM),
|
HOWTO (R_TLSM, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
32, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLSM", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
0xffffffff, /* src_mask */
|
||||||
|
0xffffffff, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
|
|
||||||
/* 0x25: TLS module relocation. */
|
/* 0x25: TLS module relocation. */
|
||||||
EMPTY_HOWTO(R_TLSML),
|
HOWTO (R_TLSML, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
32, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLSM", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
0xffffffff, /* src_mask */
|
||||||
|
0xffffffff, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
EMPTY_HOWTO(0x26),
|
EMPTY_HOWTO(0x26),
|
||||||
EMPTY_HOWTO(0x27),
|
EMPTY_HOWTO(0x27),
|
||||||
@ -1180,6 +1253,18 @@ _bfd_xcoff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
|||||||
return &xcoff_howto_table[0];
|
return &xcoff_howto_table[0];
|
||||||
case BFD_RELOC_NONE:
|
case BFD_RELOC_NONE:
|
||||||
return &xcoff_howto_table[0xf];
|
return &xcoff_howto_table[0xf];
|
||||||
|
case BFD_RELOC_PPC_TLSGD:
|
||||||
|
return &xcoff_howto_table[0x20];
|
||||||
|
case BFD_RELOC_PPC_TLSIE:
|
||||||
|
return &xcoff_howto_table[0x21];
|
||||||
|
case BFD_RELOC_PPC_TLSLD:
|
||||||
|
return &xcoff_howto_table[0x22];
|
||||||
|
case BFD_RELOC_PPC_TLSLE:
|
||||||
|
return &xcoff_howto_table[0x23];
|
||||||
|
case BFD_RELOC_PPC_TLSM:
|
||||||
|
return &xcoff_howto_table[0x24];
|
||||||
|
case BFD_RELOC_PPC_TLSML:
|
||||||
|
return &xcoff_howto_table[0x25];
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -3127,6 +3212,88 @@ xcoff_reloc_type_crel (bfd *input_bfd ATTRIBUTE_UNUSED,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bfd_boolean
|
||||||
|
xcoff_reloc_type_tls (bfd *input_bfd ATTRIBUTE_UNUSED,
|
||||||
|
asection *input_section ATTRIBUTE_UNUSED,
|
||||||
|
bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||||
|
struct internal_reloc *rel ATTRIBUTE_UNUSED,
|
||||||
|
struct internal_syment *sym ATTRIBUTE_UNUSED,
|
||||||
|
struct reloc_howto_struct *howto,
|
||||||
|
bfd_vma val,
|
||||||
|
bfd_vma addend,
|
||||||
|
bfd_vma *relocation,
|
||||||
|
bfd_byte *contents ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
struct xcoff_link_hash_entry *h;
|
||||||
|
|
||||||
|
if (0 > rel->r_symndx)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
|
||||||
|
|
||||||
|
/* FIXME: R_TLSML is targeting a internal TOC symbol, which will
|
||||||
|
make the following checks failing. It should be moved with
|
||||||
|
R_TLSM bellow once it works. */
|
||||||
|
if (howto->type == R_TLSML)
|
||||||
|
{
|
||||||
|
*relocation = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: h is sometimes null, if the TLS symbol is not exported. */
|
||||||
|
if (!h)
|
||||||
|
{
|
||||||
|
_bfd_error_handler
|
||||||
|
(_("%pB: TLS relocation at (0x%" BFD_VMA_FMT "x) over "
|
||||||
|
"internal symbols (C_HIDEXT) not yet possible\n"),
|
||||||
|
input_bfd, rel->r_vaddr);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* TLS relocations must target a TLS symbol. */
|
||||||
|
if (h->smclas != XMC_TL && h->smclas != XMC_UL)
|
||||||
|
{
|
||||||
|
_bfd_error_handler
|
||||||
|
(_("%pB: TLS relocation at (0x%" BFD_VMA_FMT "x) over "
|
||||||
|
"non-TLS symbol %s (0x%x)\n"),
|
||||||
|
input_bfd, rel->r_vaddr, h->root.root.string, h->smclas);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Local TLS relocations must target a local symbol, ie
|
||||||
|
non-imported. */
|
||||||
|
if ((rel->r_type == R_TLS_LD || rel->r_type == R_TLS_LE)
|
||||||
|
&& (((h->flags & XCOFF_DEF_REGULAR) == 0
|
||||||
|
&& (h->flags & XCOFF_DEF_DYNAMIC) != 0)
|
||||||
|
|| (h->flags & XCOFF_IMPORT) != 0))
|
||||||
|
{
|
||||||
|
_bfd_error_handler
|
||||||
|
(_("%pB: TLS local relocation at (0x%" BFD_VMA_FMT "x) over "
|
||||||
|
"imported symbol %s\n"),
|
||||||
|
input_bfd, rel->r_vaddr, h->root.root.string);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* R_TLSM and R_TLSML are relocations used by the loader.
|
||||||
|
The value must be 0.
|
||||||
|
FIXME: move R_TLSML here. */
|
||||||
|
if (howto->type == R_TLSM)
|
||||||
|
{
|
||||||
|
*relocation = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Other TLS relocations aims to put offsets from TLS pointers
|
||||||
|
starting at -0x7c00 (or -0x7800 in XCOFF64). It becomes a
|
||||||
|
simple R_POS relocation as long as .tdata and .tbss addresses
|
||||||
|
start at the same value. This is done in aix ld scripts.
|
||||||
|
TODO: implement optimization when tls size is < 62K. */
|
||||||
|
*relocation = val + addend;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
xcoff_complain_overflow_dont_func (bfd *input_bfd ATTRIBUTE_UNUSED,
|
xcoff_complain_overflow_dont_func (bfd *input_bfd ATTRIBUTE_UNUSED,
|
||||||
bfd_vma val ATTRIBUTE_UNUSED,
|
bfd_vma val ATTRIBUTE_UNUSED,
|
||||||
@ -3335,13 +3502,6 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd,
|
|||||||
quite figure out when this is useful. These relocs are
|
quite figure out when this is useful. These relocs are
|
||||||
not defined by the PowerOpen ABI.
|
not defined by the PowerOpen ABI.
|
||||||
|
|
||||||
R_TLS
|
|
||||||
R_TLS_IE
|
|
||||||
R_TLS_LD
|
|
||||||
R_TLSLE
|
|
||||||
|
|
||||||
Not yet implemented.
|
|
||||||
|
|
||||||
Supported r_type's
|
Supported r_type's
|
||||||
|
|
||||||
R_POS:
|
R_POS:
|
||||||
@ -3437,6 +3597,25 @@ xcoff_complain_overflow_unsigned_func (bfd *input_bfd,
|
|||||||
fixed address which may be modified to a relative branch.
|
fixed address which may be modified to a relative branch.
|
||||||
The PowerOpen ABI does not define this relocation type.
|
The PowerOpen ABI does not define this relocation type.
|
||||||
|
|
||||||
|
R_TLS:
|
||||||
|
Thread-local storage relocation using general-dynamic
|
||||||
|
model.
|
||||||
|
|
||||||
|
R_TLS_IE:
|
||||||
|
Thread-local storage relocation using initial-exec model.
|
||||||
|
|
||||||
|
R_TLS_LD:
|
||||||
|
Thread-local storage relocation using local-dynamic model.
|
||||||
|
|
||||||
|
R_TLS_LE:
|
||||||
|
Thread-local storage relocation using local-exec model.
|
||||||
|
|
||||||
|
R_TLS:
|
||||||
|
Tread-local storage relocation used by the loader.
|
||||||
|
|
||||||
|
R_TLSM:
|
||||||
|
Tread-local storage relocation used by the loader.
|
||||||
|
|
||||||
R_TOCU:
|
R_TOCU:
|
||||||
Upper TOC relative relocation. The value is the
|
Upper TOC relative relocation. The value is the
|
||||||
high-order 16 bit of a TOC relative relocation.
|
high-order 16 bit of a TOC relative relocation.
|
||||||
|
@ -212,12 +212,12 @@ xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] =
|
|||||||
xcoff_reloc_type_fail, /* (0x1d) */
|
xcoff_reloc_type_fail, /* (0x1d) */
|
||||||
xcoff_reloc_type_fail, /* (0x1e) */
|
xcoff_reloc_type_fail, /* (0x1e) */
|
||||||
xcoff_reloc_type_fail, /* (0x1f) */
|
xcoff_reloc_type_fail, /* (0x1f) */
|
||||||
xcoff_reloc_type_fail, /* R_TLS (0x20) */
|
xcoff_reloc_type_tls, /* R_TLS (0x20) */
|
||||||
xcoff_reloc_type_fail, /* R_TLS_IE (0x21) */
|
xcoff_reloc_type_tls, /* R_TLS_IE (0x21) */
|
||||||
xcoff_reloc_type_fail, /* R_TLS_LD (0x22) */
|
xcoff_reloc_type_tls, /* R_TLS_LD (0x22) */
|
||||||
xcoff_reloc_type_fail, /* R_TLS_LE (0x23) */
|
xcoff_reloc_type_tls, /* R_TLS_LE (0x23) */
|
||||||
xcoff_reloc_type_fail, /* R_TLSM (0x24) */
|
xcoff_reloc_type_tls, /* R_TLSM (0x24) */
|
||||||
xcoff_reloc_type_fail, /* R_TLSML (0x25) */
|
xcoff_reloc_type_tls, /* R_TLSML (0x25) */
|
||||||
xcoff_reloc_type_fail, /* (0x26) */
|
xcoff_reloc_type_fail, /* (0x26) */
|
||||||
xcoff_reloc_type_fail, /* (0x27) */
|
xcoff_reloc_type_fail, /* (0x27) */
|
||||||
xcoff_reloc_type_fail, /* (0x28) */
|
xcoff_reloc_type_fail, /* (0x28) */
|
||||||
@ -1230,24 +1230,95 @@ reloc_howto_type xcoff64_howto_table[] =
|
|||||||
0xffff, /* dst_mask */
|
0xffff, /* dst_mask */
|
||||||
FALSE), /* pcrel_offset */
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
|
|
||||||
/* 0x20: General-dynamic TLS relocation. */
|
/* 0x20: General-dynamic TLS relocation. */
|
||||||
EMPTY_HOWTO (R_TLS),
|
HOWTO (R_TLS, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
4, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
64, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLS", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
MINUS_ONE, /* src_mask */
|
||||||
|
MINUS_ONE, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* 0x21: Initial-exec TLS relocation. */
|
/* 0x21: Initial-exec TLS relocation. */
|
||||||
EMPTY_HOWTO (R_TLS_IE),
|
HOWTO (R_TLS_IE, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
4, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
64, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLS_IE", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
MINUS_ONE, /* src_mask */
|
||||||
|
MINUS_ONE, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* 0x22: Local-dynamic TLS relocation. */
|
/* 0x22: Local-dynamic TLS relocation. */
|
||||||
EMPTY_HOWTO (R_TLS_LD),
|
HOWTO (R_TLS_LD, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
4, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
64, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLS_LD", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
MINUS_ONE, /* src_mask */
|
||||||
|
MINUS_ONE, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* 0x23: Local-exec TLS relocation. */
|
/* 0x23: Local-exec TLS relocation. */
|
||||||
EMPTY_HOWTO (R_TLS_LE),
|
HOWTO (R_TLS_LE, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
4, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
64, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLS_LE", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
MINUS_ONE, /* src_mask */
|
||||||
|
MINUS_ONE, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* 0x24: TLS relocation. */
|
/* 0x24: TLS relocation. */
|
||||||
EMPTY_HOWTO(R_TLSM),
|
HOWTO (R_TLSM, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
4, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
64, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLSM", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
MINUS_ONE, /* src_mask */
|
||||||
|
MINUS_ONE, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* 0x25: TLS module relocation. */
|
/* 0x25: TLS module relocation. */
|
||||||
EMPTY_HOWTO(R_TLSML),
|
HOWTO (R_TLSML, /* type */
|
||||||
|
0, /* rightshift */
|
||||||
|
4, /* size (0 = byte, 1 = short, 2 = long) */
|
||||||
|
64, /* bitsize */
|
||||||
|
FALSE, /* pc_relative */
|
||||||
|
0, /* bitpos */
|
||||||
|
complain_overflow_bitfield, /* complain_on_overflow */
|
||||||
|
0, /* special_function */
|
||||||
|
"R_TLSM", /* name */
|
||||||
|
TRUE, /* partial_inplace */
|
||||||
|
MINUS_ONE, /* src_mask */
|
||||||
|
MINUS_ONE, /* dst_mask */
|
||||||
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
EMPTY_HOWTO(0x26),
|
EMPTY_HOWTO(0x26),
|
||||||
EMPTY_HOWTO(0x27),
|
EMPTY_HOWTO(0x27),
|
||||||
@ -1355,6 +1426,18 @@ xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
|
|||||||
return &xcoff64_howto_table[0];
|
return &xcoff64_howto_table[0];
|
||||||
case BFD_RELOC_NONE:
|
case BFD_RELOC_NONE:
|
||||||
return &xcoff64_howto_table[0xf];
|
return &xcoff64_howto_table[0xf];
|
||||||
|
case BFD_RELOC_PPC64_TLSGD:
|
||||||
|
return &xcoff64_howto_table[0x20];
|
||||||
|
case BFD_RELOC_PPC64_TLSIE:
|
||||||
|
return &xcoff64_howto_table[0x21];
|
||||||
|
case BFD_RELOC_PPC64_TLSLD:
|
||||||
|
return &xcoff64_howto_table[0x22];
|
||||||
|
case BFD_RELOC_PPC64_TLSLE:
|
||||||
|
return &xcoff64_howto_table[0x23];
|
||||||
|
case BFD_RELOC_PPC64_TLSM:
|
||||||
|
return &xcoff64_howto_table[0x24];
|
||||||
|
case BFD_RELOC_PPC64_TLSML:
|
||||||
|
return &xcoff64_howto_table[0x25];
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -548,6 +548,14 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef RS6000COFF_C
|
#ifdef RS6000COFF_C
|
||||||
|
else if (!strcmp (sec_name, _TDATA))
|
||||||
|
{
|
||||||
|
styp_flags = STYP_TDATA;
|
||||||
|
}
|
||||||
|
else if (!strcmp (sec_name, _TBSS))
|
||||||
|
{
|
||||||
|
styp_flags = STYP_TBSS;
|
||||||
|
}
|
||||||
else if (!strcmp (sec_name, _PAD))
|
else if (!strcmp (sec_name, _PAD))
|
||||||
{
|
{
|
||||||
styp_flags = STYP_PAD;
|
styp_flags = STYP_PAD;
|
||||||
@ -787,6 +795,22 @@ styp_to_sec_flags (bfd *abfd,
|
|||||||
else if (styp_flags & STYP_PAD)
|
else if (styp_flags & STYP_PAD)
|
||||||
sec_flags = 0;
|
sec_flags = 0;
|
||||||
#ifdef RS6000COFF_C
|
#ifdef RS6000COFF_C
|
||||||
|
else if (styp_flags & STYP_TDATA)
|
||||||
|
{
|
||||||
|
if (sec_flags & SEC_NEVER_LOAD)
|
||||||
|
sec_flags |= SEC_DATA | SEC_THREAD_LOCAL | SEC_COFF_SHARED_LIBRARY;
|
||||||
|
else
|
||||||
|
sec_flags |= SEC_DATA | SEC_THREAD_LOCAL | SEC_LOAD | SEC_ALLOC;
|
||||||
|
}
|
||||||
|
else if (styp_flags & STYP_TBSS)
|
||||||
|
{
|
||||||
|
#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY
|
||||||
|
if (sec_flags & SEC_NEVER_LOAD)
|
||||||
|
sec_flags |= SEC_ALLOC | SEC_THREAD_LOCAL | SEC_COFF_SHARED_LIBRARY;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
sec_flags |= SEC_ALLOC | SEC_THREAD_LOCAL;
|
||||||
|
}
|
||||||
else if (styp_flags & STYP_EXCEPT)
|
else if (styp_flags & STYP_EXCEPT)
|
||||||
sec_flags |= SEC_LOAD;
|
sec_flags |= SEC_LOAD;
|
||||||
else if (styp_flags & STYP_LOADER)
|
else if (styp_flags & STYP_LOADER)
|
||||||
@ -3168,10 +3192,15 @@ coff_compute_section_file_positions (bfd * abfd)
|
|||||||
|
|
||||||
0 .text 000054cc 10000128 10000128 00000128 2**5
|
0 .text 000054cc 10000128 10000128 00000128 2**5
|
||||||
CONTENTS, ALLOC, LOAD, CODE
|
CONTENTS, ALLOC, LOAD, CODE
|
||||||
|
|
||||||
|
Don't perform the above tweak if the previous one is .tdata,
|
||||||
|
as it will increase the memory allocated for every threads
|
||||||
|
created and not just improve performances with gdb.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!strcmp (current->name, _TEXT)
|
if ((!strcmp (current->name, _TEXT)
|
||||||
|| !strcmp (current->name, _DATA))
|
|| !strcmp (current->name, _DATA))
|
||||||
|
&& (previous == NULL || strcmp(previous->name, _TDATA)))
|
||||||
{
|
{
|
||||||
bfd_vma align = 4096;
|
bfd_vma align = 4096;
|
||||||
bfd_vma sofar_off = sofar % align;
|
bfd_vma sofar_off = sofar % align;
|
||||||
@ -3381,6 +3410,10 @@ coff_write_object_contents (bfd * abfd)
|
|||||||
asection *text_sec = NULL;
|
asection *text_sec = NULL;
|
||||||
asection *data_sec = NULL;
|
asection *data_sec = NULL;
|
||||||
asection *bss_sec = NULL;
|
asection *bss_sec = NULL;
|
||||||
|
#ifdef RS6000COFF_C
|
||||||
|
asection *tdata_sec = NULL;
|
||||||
|
asection *tbss_sec = NULL;
|
||||||
|
#endif
|
||||||
struct internal_filehdr internal_f;
|
struct internal_filehdr internal_f;
|
||||||
struct internal_aouthdr internal_a;
|
struct internal_aouthdr internal_a;
|
||||||
#ifdef COFF_LONG_SECTION_NAMES
|
#ifdef COFF_LONG_SECTION_NAMES
|
||||||
@ -3603,6 +3636,13 @@ coff_write_object_contents (bfd * abfd)
|
|||||||
data_sec = current;
|
data_sec = current;
|
||||||
else if (!strcmp (current->name, _BSS))
|
else if (!strcmp (current->name, _BSS))
|
||||||
bss_sec = current;
|
bss_sec = current;
|
||||||
|
#ifdef RS6000COFF_C
|
||||||
|
else if (!strcmp (current->name, _TDATA))
|
||||||
|
tdata_sec = current;
|
||||||
|
else if (!strcmp (current->name, _TBSS))
|
||||||
|
tbss_sec = current;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef COFF_ENCODE_ALIGNMENT
|
#ifdef COFF_ENCODE_ALIGNMENT
|
||||||
COFF_ENCODE_ALIGNMENT(section, current->alignment_power);
|
COFF_ENCODE_ALIGNMENT(section, current->alignment_power);
|
||||||
@ -4041,6 +4081,29 @@ coff_write_object_contents (bfd * abfd)
|
|||||||
else
|
else
|
||||||
internal_a.o_snbss = 0;
|
internal_a.o_snbss = 0;
|
||||||
|
|
||||||
|
if (tdata_sec != NULL)
|
||||||
|
{
|
||||||
|
internal_a.o_sntdata = tdata_sec->target_index;
|
||||||
|
/* TODO: o_flags should be set to RS6K_AOUTHDR_TLS_LE
|
||||||
|
if there is at least one R_TLS_LE relocations. */
|
||||||
|
internal_a.o_flags = 0;
|
||||||
|
#ifdef XCOFF64
|
||||||
|
internal_a.o_x64flags = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
internal_a.o_sntdata = 0;
|
||||||
|
internal_a.o_flags = 0;
|
||||||
|
#ifdef XCOFF64
|
||||||
|
internal_a.o_x64flags = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (tbss_sec != NULL)
|
||||||
|
internal_a.o_sntbss = tbss_sec->target_index;
|
||||||
|
else
|
||||||
|
internal_a.o_sntbss = 0;
|
||||||
|
|
||||||
toc = xcoff_data (abfd)->toc;
|
toc = xcoff_data (abfd)->toc;
|
||||||
internal_a.o_toc = toc;
|
internal_a.o_toc = toc;
|
||||||
internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
|
internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
|
||||||
|
@ -695,9 +695,16 @@ coff_swap_aouthdr_out (bfd * abfd, void * in, void * out)
|
|||||||
H_PUT_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
|
H_PUT_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
|
||||||
H_PUT_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
|
H_PUT_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
|
||||||
#endif
|
#endif
|
||||||
memset (aouthdr_out->o_resv2, 0, sizeof aouthdr_out->o_resv2);
|
/* TODO: set o_*psize dynamically */
|
||||||
|
H_PUT_8 (abfd, 0, aouthdr_out->o_textpsize);
|
||||||
|
H_PUT_8 (abfd, 0, aouthdr_out->o_datapsize);
|
||||||
|
H_PUT_8 (abfd, 0, aouthdr_out->o_stackpsize);
|
||||||
|
H_PUT_8 (abfd, aouthdr_in->o_flags, aouthdr_out->o_flags);
|
||||||
|
H_PUT_16 (abfd, aouthdr_in->o_sntdata, aouthdr_out->o_sntdata);
|
||||||
|
H_PUT_16 (abfd, aouthdr_in->o_sntbss, aouthdr_out->o_sntbss);
|
||||||
|
H_PUT_32 (abfd, 0, aouthdr_out->o_debugger);
|
||||||
#ifdef XCOFF64
|
#ifdef XCOFF64
|
||||||
memset (aouthdr_out->o_debugger, 0, sizeof aouthdr_out->o_debugger);
|
H_PUT_16 (abfd, aouthdr_in->o_x64flags, aouthdr_out->o_x64flags);
|
||||||
memset (aouthdr_out->o_resv3, 0, sizeof aouthdr_out->o_resv3);
|
memset (aouthdr_out->o_resv3, 0, sizeof aouthdr_out->o_resv3);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
10
bfd/libbfd.h
10
bfd/libbfd.h
@ -1564,6 +1564,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
|||||||
"BFD_RELOC_PPC_TLS",
|
"BFD_RELOC_PPC_TLS",
|
||||||
"BFD_RELOC_PPC_TLSGD",
|
"BFD_RELOC_PPC_TLSGD",
|
||||||
"BFD_RELOC_PPC_TLSLD",
|
"BFD_RELOC_PPC_TLSLD",
|
||||||
|
"BFD_RELOC_PPC_TLSLE",
|
||||||
|
"BFD_RELOC_PPC_TLSIE",
|
||||||
|
"BFD_RELOC_PPC_TLSM",
|
||||||
|
"BFD_RELOC_PPC_TLSML",
|
||||||
"BFD_RELOC_PPC_DTPMOD",
|
"BFD_RELOC_PPC_DTPMOD",
|
||||||
"BFD_RELOC_PPC_TPREL16",
|
"BFD_RELOC_PPC_TPREL16",
|
||||||
"BFD_RELOC_PPC_TPREL16_LO",
|
"BFD_RELOC_PPC_TPREL16_LO",
|
||||||
@ -1591,6 +1595,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
|||||||
"BFD_RELOC_PPC_GOT_DTPREL16_LO",
|
"BFD_RELOC_PPC_GOT_DTPREL16_LO",
|
||||||
"BFD_RELOC_PPC_GOT_DTPREL16_HI",
|
"BFD_RELOC_PPC_GOT_DTPREL16_HI",
|
||||||
"BFD_RELOC_PPC_GOT_DTPREL16_HA",
|
"BFD_RELOC_PPC_GOT_DTPREL16_HA",
|
||||||
|
"BFD_RELOC_PPC64_TLSGD",
|
||||||
|
"BFD_RELOC_PPC64_TLSLD",
|
||||||
|
"BFD_RELOC_PPC64_TLSLE",
|
||||||
|
"BFD_RELOC_PPC64_TLSIE",
|
||||||
|
"BFD_RELOC_PPC64_TLSM",
|
||||||
|
"BFD_RELOC_PPC64_TLSML",
|
||||||
"BFD_RELOC_PPC64_TPREL16_DS",
|
"BFD_RELOC_PPC64_TPREL16_DS",
|
||||||
"BFD_RELOC_PPC64_TPREL16_LO_DS",
|
"BFD_RELOC_PPC64_TPREL16_LO_DS",
|
||||||
"BFD_RELOC_PPC64_TPREL16_HIGH",
|
"BFD_RELOC_PPC64_TPREL16_HIGH",
|
||||||
|
@ -234,6 +234,7 @@ extern xcoff_reloc_function xcoff_reloc_type_rel;
|
|||||||
extern xcoff_reloc_function xcoff_reloc_type_toc;
|
extern xcoff_reloc_function xcoff_reloc_type_toc;
|
||||||
extern xcoff_reloc_function xcoff_reloc_type_ba;
|
extern xcoff_reloc_function xcoff_reloc_type_ba;
|
||||||
extern xcoff_reloc_function xcoff_reloc_type_crel;
|
extern xcoff_reloc_function xcoff_reloc_type_crel;
|
||||||
|
extern xcoff_reloc_function xcoff_reloc_type_tls;
|
||||||
|
|
||||||
/* Structure to describe dwarf sections.
|
/* Structure to describe dwarf sections.
|
||||||
Useful to convert from XCOFF section name to flag and vice-versa.
|
Useful to convert from XCOFF section name to flag and vice-versa.
|
||||||
|
20
bfd/reloc.c
20
bfd/reloc.c
@ -2943,6 +2943,14 @@ ENUMX
|
|||||||
BFD_RELOC_PPC_TLSGD
|
BFD_RELOC_PPC_TLSGD
|
||||||
ENUMX
|
ENUMX
|
||||||
BFD_RELOC_PPC_TLSLD
|
BFD_RELOC_PPC_TLSLD
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC_TLSLE
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC_TLSIE
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC_TLSM
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC_TLSML
|
||||||
ENUMX
|
ENUMX
|
||||||
BFD_RELOC_PPC_DTPMOD
|
BFD_RELOC_PPC_DTPMOD
|
||||||
ENUMX
|
ENUMX
|
||||||
@ -2997,6 +3005,18 @@ ENUMX
|
|||||||
BFD_RELOC_PPC_GOT_DTPREL16_HI
|
BFD_RELOC_PPC_GOT_DTPREL16_HI
|
||||||
ENUMX
|
ENUMX
|
||||||
BFD_RELOC_PPC_GOT_DTPREL16_HA
|
BFD_RELOC_PPC_GOT_DTPREL16_HA
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC64_TLSGD
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC64_TLSLD
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC64_TLSLE
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC64_TLSIE
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC64_TLSM
|
||||||
|
ENUMX
|
||||||
|
BFD_RELOC_PPC64_TLSML
|
||||||
ENUMX
|
ENUMX
|
||||||
BFD_RELOC_PPC64_TPREL16_DS
|
BFD_RELOC_PPC64_TPREL16_DS
|
||||||
ENUMX
|
ENUMX
|
||||||
|
@ -1814,6 +1814,12 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||||||
csect = bfd_make_section_anyway_with_flags (abfd, ".td",
|
csect = bfd_make_section_anyway_with_flags (abfd, ".td",
|
||||||
SEC_ALLOC);
|
SEC_ALLOC);
|
||||||
}
|
}
|
||||||
|
else if (aux.x_csect.x_smclas == XMC_UL)
|
||||||
|
{
|
||||||
|
/* This is a thread-local unitialized csect. */
|
||||||
|
csect = bfd_make_section_anyway_with_flags (abfd, ".tbss",
|
||||||
|
SEC_ALLOC | SEC_THREAD_LOCAL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
csect = bfd_make_section_anyway_with_flags (abfd, ".bss",
|
csect = bfd_make_section_anyway_with_flags (abfd, ".bss",
|
||||||
SEC_ALLOC);
|
SEC_ALLOC);
|
||||||
@ -2697,6 +2703,14 @@ xcoff_need_ldrel_p (struct bfd_link_info *info, struct internal_reloc *rel,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
case R_TLS:
|
||||||
|
case R_TLS_LE:
|
||||||
|
case R_TLS_IE:
|
||||||
|
case R_TLS_LD:
|
||||||
|
case R_TLSM:
|
||||||
|
case R_TLSML:
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4060,6 +4074,10 @@ xcoff_create_ldrel (bfd *output_bfd, struct xcoff_final_link_info *flinfo,
|
|||||||
ldrel.l_symndx = 1;
|
ldrel.l_symndx = 1;
|
||||||
else if (strcmp (secname, ".bss") == 0)
|
else if (strcmp (secname, ".bss") == 0)
|
||||||
ldrel.l_symndx = 2;
|
ldrel.l_symndx = 2;
|
||||||
|
else if (strcmp (secname, ".tdata") == 0)
|
||||||
|
ldrel.l_symndx = -1;
|
||||||
|
else if (strcmp (secname, ".tbss") == 0)
|
||||||
|
ldrel.l_symndx = -2;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_bfd_error_handler
|
_bfd_error_handler
|
||||||
|
@ -1,3 +1,26 @@
|
|||||||
|
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||||
|
|
||||||
|
* config/tc-ppc.c (ppc_xcoff_text_section, ppc_xcoff_data_section,
|
||||||
|
(ppc_xcoff_bss_section, ppc_xcoff_tdata_section,
|
||||||
|
(ppc_xcoff_tbss_section): New variables.
|
||||||
|
(ppc_text_subsegment, ppc_text_csects, ppc_data_subgments,
|
||||||
|
(ppc_data_csects): Removed.
|
||||||
|
(ppc_xcoff_section_is_initialized, ppc_init_xcoff_section,
|
||||||
|
ppc_xcoff_parse_cons): New functions.
|
||||||
|
(md_being): Initialize XCOFF sections.
|
||||||
|
(ppc_xcoff_suffix): Add support for TLS relocations
|
||||||
|
(fixup_size, md_apply_fix): Add support for new BFD_RELOC.
|
||||||
|
(ppc_change_csect): Handle XMC_TL, XMC_UL. Correctly, add XMC_BS
|
||||||
|
to .bss section. Handle new XCOFF section variables.
|
||||||
|
(ppc_comm): Likewise.
|
||||||
|
(ppc_toc): Likewise.
|
||||||
|
(ppc_symbol_new_hook): Likewise.
|
||||||
|
(ppc_frob_symbol): Likewise.
|
||||||
|
(ppc_fix_adjustable): Add tbss support.
|
||||||
|
* config/tc-ppc.h (TC_PARSE_CONS_EXPRESSION): New define.
|
||||||
|
(ppc_xcoff_parse_cons): Add prototype.
|
||||||
|
(struct ppc_xcoff_section): New structure.
|
||||||
|
|
||||||
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||||
|
|
||||||
* config/tc-ppc.c (ppc_xcoff_suffix): New function.
|
* config/tc-ppc.c (ppc_xcoff_suffix): New function.
|
||||||
|
@ -992,21 +992,41 @@ static bfd_boolean msolaris = SOLARIS_P;
|
|||||||
|
|
||||||
/* The RS/6000 assembler uses the .csect pseudo-op to generate code
|
/* The RS/6000 assembler uses the .csect pseudo-op to generate code
|
||||||
using a bunch of different sections. These assembler sections,
|
using a bunch of different sections. These assembler sections,
|
||||||
however, are all encompassed within the .text or .data sections of
|
however, are all encompassed within the .text, .data or .bss sections
|
||||||
the final output file. We handle this by using different
|
of the final output file. We handle this by using different
|
||||||
subsegments within these main segments. */
|
subsegments within these main segments.
|
||||||
|
.tdata and .tbss sections only have one type of csects for now,
|
||||||
|
but it's better to follow the same construction like the others. */
|
||||||
|
|
||||||
/* Next subsegment to allocate within the .text segment. */
|
struct ppc_xcoff_section ppc_xcoff_text_section;
|
||||||
static subsegT ppc_text_subsegment = 2;
|
struct ppc_xcoff_section ppc_xcoff_data_section;
|
||||||
|
struct ppc_xcoff_section ppc_xcoff_bss_section;
|
||||||
|
struct ppc_xcoff_section ppc_xcoff_tdata_section;
|
||||||
|
struct ppc_xcoff_section ppc_xcoff_tbss_section;
|
||||||
|
|
||||||
/* Linked list of csects in the text section. */
|
/* Return true if the ppc_xcoff_section structure is already
|
||||||
static symbolS *ppc_text_csects;
|
initialized. */
|
||||||
|
static bfd_boolean
|
||||||
|
ppc_xcoff_section_is_initialized (struct ppc_xcoff_section *section)
|
||||||
|
{
|
||||||
|
return section->segment != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Next subsegment to allocate within the .data segment. */
|
/* Initialize a ppc_xcoff_section.
|
||||||
static subsegT ppc_data_subsegment = 2;
|
Dummy symbols are used to ensure the position of .text over .data
|
||||||
|
and .tdata. These symbols won't be output. */
|
||||||
/* Linked list of csects in the data section. */
|
static void
|
||||||
static symbolS *ppc_data_csects;
|
ppc_init_xcoff_section (struct ppc_xcoff_section *s, segT seg,
|
||||||
|
bfd_boolean need_dummy)
|
||||||
|
{
|
||||||
|
s->segment = seg;
|
||||||
|
s->next_subsegment = 2;
|
||||||
|
if (need_dummy)
|
||||||
|
{
|
||||||
|
s->csects = symbol_make ("dummy\001");
|
||||||
|
symbol_get_tc (s->csects)->within = s->csects;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The current csect. */
|
/* The current csect. */
|
||||||
static symbolS *ppc_current_csect;
|
static symbolS *ppc_current_csect;
|
||||||
@ -1858,13 +1878,12 @@ md_begin (void)
|
|||||||
#ifdef OBJ_XCOFF
|
#ifdef OBJ_XCOFF
|
||||||
ppc_coff_debug_section = coff_section_from_bfd_index (stdoutput, N_DEBUG);
|
ppc_coff_debug_section = coff_section_from_bfd_index (stdoutput, N_DEBUG);
|
||||||
|
|
||||||
/* Create dummy symbols to serve as initial csects. This forces the
|
/* Create XCOFF sections with .text in first, as it's creating dummy symbols
|
||||||
text csects to precede the data csects. These symbols will not
|
to serve as initial csects. This forces the text csects to precede the
|
||||||
be output. */
|
data csects. These symbols will not be output. */
|
||||||
ppc_text_csects = symbol_make ("dummy\001");
|
ppc_init_xcoff_section (&ppc_xcoff_text_section, text_section, TRUE);
|
||||||
symbol_get_tc (ppc_text_csects)->within = ppc_text_csects;
|
ppc_init_xcoff_section (&ppc_xcoff_data_section, data_section, TRUE);
|
||||||
ppc_data_csects = symbol_make ("dummy\001");
|
ppc_init_xcoff_section (&ppc_xcoff_bss_section, bss_section, FALSE);
|
||||||
symbol_get_tc (ppc_data_csects)->within = ppc_data_csects;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2674,6 +2693,16 @@ ppc_xcoff_suffix (char **str_p)
|
|||||||
static const struct map_bfd mapping[] = {
|
static const struct map_bfd mapping[] = {
|
||||||
MAP ("l", BFD_RELOC_PPC_TOC16_LO),
|
MAP ("l", BFD_RELOC_PPC_TOC16_LO),
|
||||||
MAP ("u", BFD_RELOC_PPC_TOC16_HI),
|
MAP ("u", BFD_RELOC_PPC_TOC16_HI),
|
||||||
|
MAP32 ("ie", BFD_RELOC_PPC_TLSIE),
|
||||||
|
MAP32 ("ld", BFD_RELOC_PPC_TLSLD),
|
||||||
|
MAP32 ("le", BFD_RELOC_PPC_TLSLE),
|
||||||
|
MAP32 ("m", BFD_RELOC_PPC_TLSM),
|
||||||
|
MAP32 ("ml", BFD_RELOC_PPC_TLSML),
|
||||||
|
MAP64 ("ie", BFD_RELOC_PPC64_TLSIE),
|
||||||
|
MAP64 ("ld", BFD_RELOC_PPC64_TLSLD),
|
||||||
|
MAP64 ("le", BFD_RELOC_PPC64_TLSLE),
|
||||||
|
MAP64 ("m", BFD_RELOC_PPC64_TLSM),
|
||||||
|
MAP64 ("ml", BFD_RELOC_PPC64_TLSML),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (*str++ != '@')
|
if (*str++ != '@')
|
||||||
@ -2726,6 +2755,24 @@ ppc_xcoff_fixup_addis (char *rt_e, char *d_e, char *ra_e)
|
|||||||
free (save_ra);
|
free (save_ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Support @ie, etc. on constants emitted via .short, .int etc. */
|
||||||
|
|
||||||
|
bfd_reloc_code_real_type
|
||||||
|
ppc_xcoff_parse_cons (expressionS *exp, unsigned int nbytes)
|
||||||
|
{
|
||||||
|
expression (exp);
|
||||||
|
if (nbytes >= 2 && *input_line_pointer == '@')
|
||||||
|
return ppc_xcoff_suffix (&input_line_pointer);
|
||||||
|
|
||||||
|
/* There isn't any @ symbol for default TLS relocations (R_TLS). */
|
||||||
|
if (exp->X_add_symbol != NULL
|
||||||
|
&& (symbol_get_tc (exp->X_add_symbol)->symbol_class == XMC_TL
|
||||||
|
|| symbol_get_tc (exp->X_add_symbol)->symbol_class == XMC_UL))
|
||||||
|
return (ppc_obj64 ? BFD_RELOC_PPC64_TLSGD: BFD_RELOC_PPC_TLSGD);
|
||||||
|
|
||||||
|
return BFD_RELOC_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* OBJ_XCOFF */
|
#endif /* OBJ_XCOFF */
|
||||||
|
|
||||||
#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
|
#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
|
||||||
@ -3052,6 +3099,10 @@ fixup_size (bfd_reloc_code_real_type reloc, bfd_boolean *pc_relative)
|
|||||||
case BFD_RELOC_PPC_TLS:
|
case BFD_RELOC_PPC_TLS:
|
||||||
case BFD_RELOC_PPC_TLSGD:
|
case BFD_RELOC_PPC_TLSGD:
|
||||||
case BFD_RELOC_PPC_TLSLD:
|
case BFD_RELOC_PPC_TLSLD:
|
||||||
|
case BFD_RELOC_PPC_TLSLE:
|
||||||
|
case BFD_RELOC_PPC_TLSIE:
|
||||||
|
case BFD_RELOC_PPC_TLSM:
|
||||||
|
case BFD_RELOC_PPC_TLSML:
|
||||||
case BFD_RELOC_PPC_VLE_HA16A:
|
case BFD_RELOC_PPC_VLE_HA16A:
|
||||||
case BFD_RELOC_PPC_VLE_HA16D:
|
case BFD_RELOC_PPC_VLE_HA16D:
|
||||||
case BFD_RELOC_PPC_VLE_HI16A:
|
case BFD_RELOC_PPC_VLE_HI16A:
|
||||||
@ -3111,6 +3162,12 @@ fixup_size (bfd_reloc_code_real_type reloc, bfd_boolean *pc_relative)
|
|||||||
case BFD_RELOC_PPC64_TPREL34:
|
case BFD_RELOC_PPC64_TPREL34:
|
||||||
case BFD_RELOC_PPC64_DTPREL34:
|
case BFD_RELOC_PPC64_DTPREL34:
|
||||||
case BFD_RELOC_PPC64_TOC:
|
case BFD_RELOC_PPC64_TOC:
|
||||||
|
case BFD_RELOC_PPC64_TLSGD:
|
||||||
|
case BFD_RELOC_PPC64_TLSLD:
|
||||||
|
case BFD_RELOC_PPC64_TLSLE:
|
||||||
|
case BFD_RELOC_PPC64_TLSIE:
|
||||||
|
case BFD_RELOC_PPC64_TLSM:
|
||||||
|
case BFD_RELOC_PPC64_TLSML:
|
||||||
size = 8;
|
size = 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4205,7 +4262,9 @@ static bfd_boolean ppc_stab_symbol;
|
|||||||
/* The .comm and .lcomm pseudo-ops for XCOFF. XCOFF puts common
|
/* The .comm and .lcomm pseudo-ops for XCOFF. XCOFF puts common
|
||||||
symbols in the .bss segment as though they were local common
|
symbols in the .bss segment as though they were local common
|
||||||
symbols, and uses a different smclas. The native Aix 4.3.3 assembler
|
symbols, and uses a different smclas. The native Aix 4.3.3 assembler
|
||||||
aligns .comm and .lcomm to 4 bytes. */
|
aligns .comm and .lcomm to 4 bytes.
|
||||||
|
Symbols having a XMC_UL storage class are uninialized thread-local
|
||||||
|
data. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ppc_comm (int lcomm)
|
ppc_comm (int lcomm)
|
||||||
@ -4220,6 +4279,7 @@ ppc_comm (int lcomm)
|
|||||||
symbolS *lcomm_sym = NULL;
|
symbolS *lcomm_sym = NULL;
|
||||||
symbolS *sym;
|
symbolS *sym;
|
||||||
char *pfrag;
|
char *pfrag;
|
||||||
|
struct ppc_xcoff_section *section;
|
||||||
|
|
||||||
endc = get_symbol_name (&name);
|
endc = get_symbol_name (&name);
|
||||||
end_name = input_line_pointer;
|
end_name = input_line_pointer;
|
||||||
@ -4312,7 +4372,23 @@ ppc_comm (int lcomm)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
record_alignment (bss_section, align);
|
if (symbol_get_tc (sym)->symbol_class == XMC_UL
|
||||||
|
|| (lcomm && symbol_get_tc (lcomm_sym)->symbol_class == XMC_UL))
|
||||||
|
{
|
||||||
|
section = &ppc_xcoff_tbss_section;
|
||||||
|
if (!ppc_xcoff_section_is_initialized (section))
|
||||||
|
{
|
||||||
|
ppc_init_xcoff_section (section,
|
||||||
|
subseg_new (".tbss", 0), FALSE);
|
||||||
|
bfd_set_section_flags (section->segment,
|
||||||
|
SEC_ALLOC | SEC_THREAD_LOCAL);
|
||||||
|
seg_info (section->segment)->bss = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
section = &ppc_xcoff_bss_section;
|
||||||
|
|
||||||
|
record_alignment (section->segment, align);
|
||||||
|
|
||||||
if (! lcomm
|
if (! lcomm
|
||||||
|| ! S_IS_DEFINED (lcomm_sym))
|
|| ! S_IS_DEFINED (lcomm_sym))
|
||||||
@ -4333,14 +4409,14 @@ ppc_comm (int lcomm)
|
|||||||
def_size = 0;
|
def_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
subseg_set (bss_section, 1);
|
subseg_set (section->segment, 1);
|
||||||
frag_align (align, 0, 0);
|
frag_align (align, 0, 0);
|
||||||
|
|
||||||
symbol_set_frag (def_sym, frag_now);
|
symbol_set_frag (def_sym, frag_now);
|
||||||
pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, def_sym,
|
pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, def_sym,
|
||||||
def_size, (char *) NULL);
|
def_size, (char *) NULL);
|
||||||
*pfrag = 0;
|
*pfrag = 0;
|
||||||
S_SET_SEGMENT (def_sym, bss_section);
|
S_SET_SEGMENT (def_sym, section->segment);
|
||||||
symbol_get_tc (def_sym)->align = align;
|
symbol_get_tc (def_sym)->align = align;
|
||||||
}
|
}
|
||||||
else if (lcomm)
|
else if (lcomm)
|
||||||
@ -4356,7 +4432,7 @@ ppc_comm (int lcomm)
|
|||||||
if (lcomm)
|
if (lcomm)
|
||||||
{
|
{
|
||||||
/* Make sym an offset from lcomm_sym. */
|
/* Make sym an offset from lcomm_sym. */
|
||||||
S_SET_SEGMENT (sym, bss_section);
|
S_SET_SEGMENT (sym, section->segment);
|
||||||
symbol_set_frag (sym, symbol_get_frag (lcomm_sym));
|
symbol_set_frag (sym, symbol_get_frag (lcomm_sym));
|
||||||
S_SET_VALUE (sym, symbol_get_frag (lcomm_sym)->fr_offset);
|
S_SET_VALUE (sym, symbol_get_frag (lcomm_sym)->fr_offset);
|
||||||
symbol_get_frag (lcomm_sym)->fr_offset += size;
|
symbol_get_frag (lcomm_sym)->fr_offset += size;
|
||||||
@ -4414,7 +4490,7 @@ ppc_change_csect (symbolS *sym, offsetT align)
|
|||||||
subseg_set (S_GET_SEGMENT (sym), symbol_get_tc (sym)->subseg);
|
subseg_set (S_GET_SEGMENT (sym), symbol_get_tc (sym)->subseg);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
symbolS **list_ptr;
|
struct ppc_xcoff_section *section;
|
||||||
int after_toc;
|
int after_toc;
|
||||||
int hold_chunksize;
|
int hold_chunksize;
|
||||||
symbolS *list;
|
symbolS *list;
|
||||||
@ -4436,10 +4512,7 @@ ppc_change_csect (symbolS *sym, offsetT align)
|
|||||||
case XMC_SV:
|
case XMC_SV:
|
||||||
case XMC_TI:
|
case XMC_TI:
|
||||||
case XMC_TB:
|
case XMC_TB:
|
||||||
S_SET_SEGMENT (sym, text_section);
|
section = &ppc_xcoff_text_section;
|
||||||
symbol_get_tc (sym)->subseg = ppc_text_subsegment;
|
|
||||||
++ppc_text_subsegment;
|
|
||||||
list_ptr = &ppc_text_csects;
|
|
||||||
is_code = 1;
|
is_code = 1;
|
||||||
break;
|
break;
|
||||||
case XMC_RW:
|
case XMC_RW:
|
||||||
@ -4448,21 +4521,48 @@ ppc_change_csect (symbolS *sym, offsetT align)
|
|||||||
case XMC_TE:
|
case XMC_TE:
|
||||||
case XMC_DS:
|
case XMC_DS:
|
||||||
case XMC_UA:
|
case XMC_UA:
|
||||||
case XMC_BS:
|
|
||||||
case XMC_UC:
|
case XMC_UC:
|
||||||
|
section = &ppc_xcoff_data_section;
|
||||||
if (ppc_toc_csect != NULL
|
if (ppc_toc_csect != NULL
|
||||||
&& (symbol_get_tc (ppc_toc_csect)->subseg + 1
|
&& (symbol_get_tc (ppc_toc_csect)->subseg + 1
|
||||||
== ppc_data_subsegment))
|
== section->next_subsegment))
|
||||||
after_toc = 1;
|
after_toc = 1;
|
||||||
S_SET_SEGMENT (sym, data_section);
|
break;
|
||||||
symbol_get_tc (sym)->subseg = ppc_data_subsegment;
|
case XMC_BS:
|
||||||
++ppc_data_subsegment;
|
section = &ppc_xcoff_bss_section;
|
||||||
list_ptr = &ppc_data_csects;
|
break;
|
||||||
|
case XMC_TL:
|
||||||
|
section = &ppc_xcoff_tdata_section;
|
||||||
|
/* Create .tdata section if not yet done. */
|
||||||
|
if (!ppc_xcoff_section_is_initialized (section))
|
||||||
|
{
|
||||||
|
ppc_init_xcoff_section (section, subseg_new (".tdata", 0),
|
||||||
|
TRUE);
|
||||||
|
bfd_set_section_flags (section->segment, SEC_ALLOC
|
||||||
|
| SEC_LOAD | SEC_RELOC | SEC_DATA
|
||||||
|
| SEC_THREAD_LOCAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XMC_UL:
|
||||||
|
section = &ppc_xcoff_tbss_section;
|
||||||
|
/* Create .tbss section if not yet done. */
|
||||||
|
if (!ppc_xcoff_section_is_initialized (section))
|
||||||
|
{
|
||||||
|
ppc_init_xcoff_section (section, subseg_new (".tbss", 0),
|
||||||
|
FALSE);
|
||||||
|
bfd_set_section_flags (section->segment, SEC_ALLOC |
|
||||||
|
SEC_THREAD_LOCAL);
|
||||||
|
seg_info (section->segment)->bss = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
S_SET_SEGMENT (sym, section->segment);
|
||||||
|
symbol_get_tc (sym)->subseg = section->next_subsegment;
|
||||||
|
++section->next_subsegment;
|
||||||
|
|
||||||
/* We set the obstack chunk size to a small value before
|
/* We set the obstack chunk size to a small value before
|
||||||
changing subsegments, so that we don't use a lot of memory
|
changing subsegments, so that we don't use a lot of memory
|
||||||
space for what may be a small section. */
|
space for what may be a small section. */
|
||||||
@ -4490,7 +4590,7 @@ ppc_change_csect (symbolS *sym, offsetT align)
|
|||||||
symbol_get_tc (sym)->output = 1;
|
symbol_get_tc (sym)->output = 1;
|
||||||
symbol_get_tc (sym)->within = sym;
|
symbol_get_tc (sym)->within = sym;
|
||||||
|
|
||||||
for (list = *list_ptr;
|
for (list = section->csects;
|
||||||
symbol_get_tc (list)->next != (symbolS *) NULL;
|
symbol_get_tc (list)->next != (symbolS *) NULL;
|
||||||
list = symbol_get_tc (list)->next)
|
list = symbol_get_tc (list)->next)
|
||||||
;
|
;
|
||||||
@ -5329,8 +5429,8 @@ ppc_toc (int ignore ATTRIBUTE_UNUSED)
|
|||||||
symbolS *sym;
|
symbolS *sym;
|
||||||
symbolS *list;
|
symbolS *list;
|
||||||
|
|
||||||
subseg = ppc_data_subsegment;
|
subseg = ppc_xcoff_data_section.next_subsegment;
|
||||||
++ppc_data_subsegment;
|
++ppc_xcoff_data_section.next_subsegment;
|
||||||
|
|
||||||
subseg_new (segment_name (data_section), subseg);
|
subseg_new (segment_name (data_section), subseg);
|
||||||
ppc_toc_frag = frag_now;
|
ppc_toc_frag = frag_now;
|
||||||
@ -5345,7 +5445,7 @@ ppc_toc (int ignore ATTRIBUTE_UNUSED)
|
|||||||
|
|
||||||
ppc_toc_csect = sym;
|
ppc_toc_csect = sym;
|
||||||
|
|
||||||
for (list = ppc_data_csects;
|
for (list = ppc_xcoff_data_section.csects;
|
||||||
symbol_get_tc (list)->next != (symbolS *) NULL;
|
symbol_get_tc (list)->next != (symbolS *) NULL;
|
||||||
list = symbol_get_tc (list)->next)
|
list = symbol_get_tc (list)->next)
|
||||||
;
|
;
|
||||||
@ -5711,12 +5811,16 @@ ppc_symbol_new_hook (symbolS *sym)
|
|||||||
tc->symbol_class = XMC_TC0;
|
tc->symbol_class = XMC_TC0;
|
||||||
else if (strcmp (s, "TE]") == 0)
|
else if (strcmp (s, "TE]") == 0)
|
||||||
tc->symbol_class = XMC_TE;
|
tc->symbol_class = XMC_TE;
|
||||||
|
else if (strcmp (s, "TL]") == 0)
|
||||||
|
tc->symbol_class = XMC_TL;
|
||||||
break;
|
break;
|
||||||
case 'U':
|
case 'U':
|
||||||
if (strcmp (s, "UA]") == 0)
|
if (strcmp (s, "UA]") == 0)
|
||||||
tc->symbol_class = XMC_UA;
|
tc->symbol_class = XMC_UA;
|
||||||
else if (strcmp (s, "UC]") == 0)
|
else if (strcmp (s, "UC]") == 0)
|
||||||
tc->symbol_class = XMC_UC;
|
tc->symbol_class = XMC_UC;
|
||||||
|
else if (strcmp (s, "UL]") == 0)
|
||||||
|
tc->symbol_class = XMC_UL;
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
if (strcmp (s, "XO]") == 0)
|
if (strcmp (s, "XO]") == 0)
|
||||||
@ -5858,12 +5962,15 @@ ppc_frob_symbol (symbolS *sym)
|
|||||||
}
|
}
|
||||||
a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_SD;
|
a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_SD;
|
||||||
}
|
}
|
||||||
else if (S_GET_SEGMENT (sym) == bss_section)
|
else if (S_GET_SEGMENT (sym) == bss_section
|
||||||
|
|| S_GET_SEGMENT (sym) == ppc_xcoff_tbss_section.segment)
|
||||||
{
|
{
|
||||||
/* This is a common symbol. */
|
/* This is a common symbol. */
|
||||||
a->x_csect.x_scnlen.l = symbol_get_frag (sym)->fr_offset;
|
a->x_csect.x_scnlen.l = symbol_get_frag (sym)->fr_offset;
|
||||||
a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_CM;
|
a->x_csect.x_smtyp = (symbol_get_tc (sym)->align << 3) | XTY_CM;
|
||||||
if (S_IS_EXTERNAL (sym))
|
if (S_GET_SEGMENT (sym) == ppc_xcoff_tbss_section.segment)
|
||||||
|
symbol_get_tc (sym)->symbol_class = XMC_UL;
|
||||||
|
else if (S_IS_EXTERNAL (sym))
|
||||||
symbol_get_tc (sym)->symbol_class = XMC_RW;
|
symbol_get_tc (sym)->symbol_class = XMC_RW;
|
||||||
else
|
else
|
||||||
symbol_get_tc (sym)->symbol_class = XMC_BS;
|
symbol_get_tc (sym)->symbol_class = XMC_BS;
|
||||||
@ -5917,9 +6024,11 @@ ppc_frob_symbol (symbolS *sym)
|
|||||||
/* This is a normal symbol definition. x_scnlen is the
|
/* This is a normal symbol definition. x_scnlen is the
|
||||||
symbol index of the containing csect. */
|
symbol index of the containing csect. */
|
||||||
if (S_GET_SEGMENT (sym) == text_section)
|
if (S_GET_SEGMENT (sym) == text_section)
|
||||||
csect = ppc_text_csects;
|
csect = ppc_xcoff_text_section.csects;
|
||||||
else if (S_GET_SEGMENT (sym) == data_section)
|
else if (S_GET_SEGMENT (sym) == data_section)
|
||||||
csect = ppc_data_csects;
|
csect = ppc_xcoff_data_section.csects;
|
||||||
|
else if (S_GET_SEGMENT (sym) == ppc_xcoff_tdata_section.segment)
|
||||||
|
csect = ppc_xcoff_tdata_section.csects;
|
||||||
else
|
else
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
@ -6201,6 +6310,7 @@ ppc_fix_adjustable (fixS *fix)
|
|||||||
&& tc->symbol_class != XMC_TC
|
&& tc->symbol_class != XMC_TC
|
||||||
&& tc->symbol_class != XMC_TE
|
&& tc->symbol_class != XMC_TE
|
||||||
&& symseg != bss_section
|
&& symseg != bss_section
|
||||||
|
&& symseg != ppc_xcoff_tbss_section.segment
|
||||||
/* Don't adjust if this is a reloc in the toc section. */
|
/* Don't adjust if this is a reloc in the toc section. */
|
||||||
&& (symseg != data_section
|
&& (symseg != data_section
|
||||||
|| ppc_toc_csect == NULL
|
|| ppc_toc_csect == NULL
|
||||||
@ -7134,6 +7244,37 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OBJ_XCOFF
|
#ifdef OBJ_XCOFF
|
||||||
|
case BFD_RELOC_PPC_TLSGD:
|
||||||
|
case BFD_RELOC_PPC_TLSLD:
|
||||||
|
case BFD_RELOC_PPC_TLSLE:
|
||||||
|
case BFD_RELOC_PPC_TLSIE:
|
||||||
|
case BFD_RELOC_PPC_TLSM:
|
||||||
|
case BFD_RELOC_PPC64_TLSGD:
|
||||||
|
case BFD_RELOC_PPC64_TLSLD:
|
||||||
|
case BFD_RELOC_PPC64_TLSLE:
|
||||||
|
case BFD_RELOC_PPC64_TLSIE:
|
||||||
|
case BFD_RELOC_PPC64_TLSM:
|
||||||
|
gas_assert (fixP->fx_addsy != NULL);
|
||||||
|
S_SET_THREAD_LOCAL (fixP->fx_addsy);
|
||||||
|
fieldval = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* TLSML relocations are targeting a XMC_TC symbol named
|
||||||
|
"_$TLSML". We can't check earlier because the relocation
|
||||||
|
can target any symbol name which will be latter .rename
|
||||||
|
to "_$TLSML". */
|
||||||
|
case BFD_RELOC_PPC_TLSML:
|
||||||
|
case BFD_RELOC_PPC64_TLSML:
|
||||||
|
gas_assert (fixP->fx_addsy != NULL);
|
||||||
|
if (strcmp (symbol_get_tc (fixP->fx_addsy)->real_name, "_$TLSML") != 0)
|
||||||
|
{
|
||||||
|
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||||
|
_("R_TLSML relocation doesn't target a "
|
||||||
|
"symbol named \"_$TLSML\". %s"), S_GET_NAME(fixP->fx_addsy));
|
||||||
|
}
|
||||||
|
fieldval = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_NONE:
|
case BFD_RELOC_NONE:
|
||||||
#endif
|
#endif
|
||||||
case BFD_RELOC_CTOR:
|
case BFD_RELOC_CTOR:
|
||||||
|
@ -189,6 +189,23 @@ do { \
|
|||||||
extern void ppc_xcoff_end (void);
|
extern void ppc_xcoff_end (void);
|
||||||
#define md_end ppc_xcoff_end
|
#define md_end ppc_xcoff_end
|
||||||
|
|
||||||
|
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
|
||||||
|
ppc_xcoff_parse_cons (EXP, NBYTES)
|
||||||
|
extern bfd_reloc_code_real_type ppc_xcoff_parse_cons (expressionS *,
|
||||||
|
unsigned int);
|
||||||
|
/* XCOFF format allows only few predefined sections. Gather all
|
||||||
|
information in a common structure. */
|
||||||
|
struct ppc_xcoff_section {
|
||||||
|
/* Main segment of the section. */
|
||||||
|
segT segment;
|
||||||
|
|
||||||
|
/* Next subsegment to allocate within the segment. */
|
||||||
|
subsegT next_subsegment;
|
||||||
|
|
||||||
|
/* Linked list of csects in the section. */
|
||||||
|
symbolS *csects;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* OBJ_XCOFF */
|
#endif /* OBJ_XCOFF */
|
||||||
|
|
||||||
#define tc_new_dot_label(sym) ppc_new_dot_label (sym)
|
#define tc_new_dot_label(sym) ppc_new_dot_label (sym)
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||||
|
|
||||||
|
* coff/internal.h (struct internal_aouthdr): Add new fields.
|
||||||
|
* coff/rs6000.h (AOUTHDRÃ): Add new fields.
|
||||||
|
* coff/rs6k64.h (struct external_filehdr): Likewise.
|
||||||
|
* coff/xcoff.h (_TDATA), _TBSS): New defines
|
||||||
|
(RS6K_AOUTHDR_TLS_LE, RS6K_AOUTHDR_RAS, RS6K_AOUTHDR_ALGNTDATA,
|
||||||
|
RS6K_AOUTHDR_SHR_SYMTAB, RS6K_AOUTHDR_FORK_POLICY,
|
||||||
|
RS6K_AOUTHDR_FORK_COR): New defines.
|
||||||
|
(XMC_TU): Removed.
|
||||||
|
(XMC_UL): New define.
|
||||||
|
|
||||||
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||||
|
|
||||||
* coff/xcoff.h (R_RTB): Remove.
|
* coff/xcoff.h (R_RTB): Remove.
|
||||||
|
@ -263,8 +263,13 @@ struct internal_aouthdr
|
|||||||
short o_algndata; /* max alignment for data */
|
short o_algndata; /* max alignment for data */
|
||||||
short o_modtype; /* Module type field, 1R,RE,RO */
|
short o_modtype; /* Module type field, 1R,RE,RO */
|
||||||
short o_cputype; /* Encoded CPU type */
|
short o_cputype; /* Encoded CPU type */
|
||||||
bfd_vma o_maxstack; /* max stack size allowed. */
|
bfd_vma o_maxstack; /* max stack size allowed. */
|
||||||
bfd_vma o_maxdata; /* max data size allowed. */
|
bfd_vma o_maxdata; /* max data size allowed. */
|
||||||
|
char o_flags; /* Flags and TLS alignment */
|
||||||
|
short o_sntdata; /* section number for tdata */
|
||||||
|
short o_sntbss; /* section number for tbss */
|
||||||
|
short o_x64flags; /* XCOFF64 flags */
|
||||||
|
|
||||||
|
|
||||||
/* ECOFF stuff */
|
/* ECOFF stuff */
|
||||||
bfd_vma bss_start; /* Base of bss section. */
|
bfd_vma bss_start; /* Base of bss section. */
|
||||||
|
@ -48,28 +48,34 @@ struct external_filehdr {
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned char magic[2]; /* type of file */
|
unsigned char magic[2]; /* type of file */
|
||||||
unsigned char vstamp[2]; /* version stamp */
|
unsigned char vstamp[2]; /* version stamp */
|
||||||
unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */
|
unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */
|
||||||
unsigned char dsize[4]; /* initialized data " " */
|
unsigned char dsize[4]; /* initialized data " " */
|
||||||
unsigned char bsize[4]; /* uninitialized data " " */
|
unsigned char bsize[4]; /* uninitialized data " " */
|
||||||
unsigned char entry[4]; /* entry pt. */
|
unsigned char entry[4]; /* entry pt. */
|
||||||
unsigned char text_start[4]; /* base of text used for this file */
|
unsigned char text_start[4]; /* base of text used for this file */
|
||||||
unsigned char data_start[4]; /* base of data used for this file */
|
unsigned char data_start[4]; /* base of data used for this file */
|
||||||
unsigned char o_toc[4]; /* address of TOC */
|
unsigned char o_toc[4]; /* address of TOC */
|
||||||
unsigned char o_snentry[2]; /* section number of entry point */
|
unsigned char o_snentry[2]; /* section number of entry point */
|
||||||
unsigned char o_sntext[2]; /* section number of .text section */
|
unsigned char o_sntext[2]; /* section number of .text section */
|
||||||
unsigned char o_sndata[2]; /* section number of .data section */
|
unsigned char o_sndata[2]; /* section number of .data section */
|
||||||
unsigned char o_sntoc[2]; /* section number of TOC */
|
unsigned char o_sntoc[2]; /* section number of TOC */
|
||||||
unsigned char o_snloader[2]; /* section number of .loader section */
|
unsigned char o_snloader[2]; /* section number of .loader section */
|
||||||
unsigned char o_snbss[2]; /* section number of .bss section */
|
unsigned char o_snbss[2]; /* section number of .bss section */
|
||||||
unsigned char o_algntext[2]; /* .text alignment */
|
unsigned char o_algntext[2]; /* .text alignment */
|
||||||
unsigned char o_algndata[2]; /* .data alignment */
|
unsigned char o_algndata[2]; /* .data alignment */
|
||||||
unsigned char o_modtype[2]; /* module type (??) */
|
unsigned char o_modtype[2]; /* module type (??) */
|
||||||
unsigned char o_cputype[2]; /* cpu type */
|
unsigned char o_cputype[2]; /* cpu type */
|
||||||
unsigned char o_maxstack[4]; /* max stack size (??) */
|
unsigned char o_maxstack[4]; /* max stack size (??) */
|
||||||
unsigned char o_maxdata[4]; /* max data size (??) */
|
unsigned char o_maxdata[4]; /* max data size (??) */
|
||||||
unsigned char o_resv2[12]; /* reserved */
|
unsigned char o_debugger[4]; /* reserved */
|
||||||
|
unsigned char o_textpsize[1]; /* text page size */
|
||||||
|
unsigned char o_datapsize[1]; /* data page size */
|
||||||
|
unsigned char o_stackpsize[1]; /* stack page size */
|
||||||
|
unsigned char o_flags[1]; /* Flags and TLS alignment */
|
||||||
|
unsigned char o_sntdata[2]; /* section number of .tdata section */
|
||||||
|
unsigned char o_sntbss[2]; /* section number of .tbss section */
|
||||||
}
|
}
|
||||||
AOUTHDR;
|
AOUTHDR;
|
||||||
|
|
||||||
|
@ -39,32 +39,38 @@ struct external_filehdr
|
|||||||
|
|
||||||
/********************** AOUT "OPTIONAL HEADER" **********************/
|
/********************** AOUT "OPTIONAL HEADER" **********************/
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned char magic[2]; /* type of file */
|
unsigned char magic[2]; /* type of file */
|
||||||
unsigned char vstamp[2]; /* version stamp */
|
unsigned char vstamp[2]; /* version stamp */
|
||||||
unsigned char o_debugger[4]; /* reserved */
|
unsigned char o_debugger[4]; /* reserved */
|
||||||
unsigned char text_start[8]; /* base of text used for this file */
|
unsigned char text_start[8]; /* base of text used for this file */
|
||||||
unsigned char data_start[8]; /* base of data used for this file */
|
unsigned char data_start[8]; /* base of data used for this file */
|
||||||
unsigned char o_toc[8]; /* address of TOC */
|
unsigned char o_toc[8]; /* address of TOC */
|
||||||
unsigned char o_snentry[2]; /* section number of entry point */
|
unsigned char o_snentry[2]; /* section number of entry point */
|
||||||
unsigned char o_sntext[2]; /* section number of .text section */
|
unsigned char o_sntext[2]; /* section number of .text section */
|
||||||
unsigned char o_sndata[2]; /* section number of .data section */
|
unsigned char o_sndata[2]; /* section number of .data section */
|
||||||
unsigned char o_sntoc[2]; /* section number of TOC */
|
unsigned char o_sntoc[2]; /* section number of TOC */
|
||||||
unsigned char o_snloader[2]; /* section number of .loader section */
|
unsigned char o_snloader[2]; /* section number of .loader section */
|
||||||
unsigned char o_snbss[2]; /* section number of .bss section */
|
unsigned char o_snbss[2]; /* section number of .bss section */
|
||||||
unsigned char o_algntext[2]; /* .text alignment */
|
unsigned char o_algntext[2]; /* .text alignment */
|
||||||
unsigned char o_algndata[2]; /* .data alignment */
|
unsigned char o_algndata[2]; /* .data alignment */
|
||||||
unsigned char o_modtype[2]; /* module type (??) */
|
unsigned char o_modtype[2]; /* module type (??) */
|
||||||
unsigned char o_cputype[2]; /* cpu type */
|
unsigned char o_cputype[2]; /* cpu type */
|
||||||
unsigned char o_resv2[4]; /* reserved */
|
unsigned char o_textpsize[1]; /* text page size */
|
||||||
unsigned char tsize[8]; /* text size bytes, padded to FW bdry */
|
unsigned char o_datapsize[1]; /* data page size */
|
||||||
unsigned char dsize[8]; /* initialized data " " */
|
unsigned char o_stackpsize[1]; /* stack page size */
|
||||||
unsigned char bsize[8]; /* uninitialized data " " */
|
unsigned char o_flags[1]; /* Flags and TLS alignment */
|
||||||
unsigned char entry[8]; /* entry pt. */
|
unsigned char tsize[8]; /* text size bytes, padded to FW bdry */
|
||||||
unsigned char o_maxstack[8]; /* max stack size (??) */
|
unsigned char dsize[8]; /* initialized data " " */
|
||||||
unsigned char o_maxdata[8]; /* max data size (??) */
|
unsigned char bsize[8]; /* uninitialized data " " */
|
||||||
unsigned char o_resv3[16]; /* reserved */
|
unsigned char entry[8]; /* entry pt. */
|
||||||
|
unsigned char o_maxstack[8]; /* max stack size (??) */
|
||||||
|
unsigned char o_maxdata[8]; /* max data size (??) */
|
||||||
|
unsigned char o_sntdata[2]; /* section number of .tdata section */
|
||||||
|
unsigned char o_sntbss[2]; /* section number of .tbss section */
|
||||||
|
unsigned char o_x64flags[2]; /* XCOFF64 flags */
|
||||||
|
unsigned char o_resv3[10]; /* reserved */
|
||||||
}
|
}
|
||||||
AOUTHDR;
|
AOUTHDR;
|
||||||
|
|
||||||
|
@ -46,6 +46,8 @@
|
|||||||
#define _TEXT ".text"
|
#define _TEXT ".text"
|
||||||
#define _DATA ".data"
|
#define _DATA ".data"
|
||||||
#define _BSS ".bss"
|
#define _BSS ".bss"
|
||||||
|
#define _TDATA ".tdata"
|
||||||
|
#define _TBSS ".tbss"
|
||||||
#define _PAD ".pad"
|
#define _PAD ".pad"
|
||||||
#define _LOADER ".loader"
|
#define _LOADER ".loader"
|
||||||
#define _EXCEPT ".except"
|
#define _EXCEPT ".except"
|
||||||
@ -93,8 +95,19 @@
|
|||||||
#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */
|
#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */
|
||||||
#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */
|
#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */
|
||||||
|
|
||||||
/* XCOFF relocation types.
|
/* Flags for aouthdr o_flags */
|
||||||
The relocations are described in the function
|
#define RS6K_AOUTHDR_TLS_LE 0x80 /* TLS local-exec code was generated */
|
||||||
|
#define RS6K_AOUTHDR_RAS 0x40 /* kernel module is key & recovery safe */
|
||||||
|
#define RS6K_AOUTHDR_ALGNTDATA 0xf /* TLS alignment */
|
||||||
|
|
||||||
|
/* Flags for aouthdr o_x64flags */
|
||||||
|
#define RS6K_AOUTHDR_SHR_SYMTAB 0x8000
|
||||||
|
#define RS6K_AOUTHDR_FORK_POLICY 0x4000
|
||||||
|
#define RS6K_AOUTHDR_FORK_COR 0x2000
|
||||||
|
|
||||||
|
|
||||||
|
/* XCOFF relocation types.
|
||||||
|
The relocations are described in the function
|
||||||
xcoff[64]_ppc_relocate_section in coff64-rs6000.c and coff-rs6000.c */
|
xcoff[64]_ppc_relocate_section in coff64-rs6000.c and coff-rs6000.c */
|
||||||
|
|
||||||
#define R_POS (0x00)
|
#define R_POS (0x00)
|
||||||
@ -171,7 +184,7 @@
|
|||||||
#define XMC_SV3264 18 /* Read-only 32 or 64 bit supervisor call */
|
#define XMC_SV3264 18 /* Read-only 32 or 64 bit supervisor call */
|
||||||
/* 19 ??? */
|
/* 19 ??? */
|
||||||
#define XMC_TL 20 /* Read-write initialized TLS data */
|
#define XMC_TL 20 /* Read-write initialized TLS data */
|
||||||
#define XMC_TU 21 /* Read-write uninitialized TLS data */
|
#define XMC_UL 21 /* Read-write uninitialized TLS data */
|
||||||
#define XMC_TE 22 /* Same as XMC_TC but mapped after it */
|
#define XMC_TE 22 /* Same as XMC_TC but mapped after it */
|
||||||
|
|
||||||
/* The ldhdr structure. This appears at the start of the .loader
|
/* The ldhdr structure. This appears at the start of the .loader
|
||||||
|
15
ld/ChangeLog
15
ld/ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||||
|
|
||||||
|
* emultempl/aix.em: Ensure .tdata section is removed
|
||||||
|
if empty, even with -r flag.
|
||||||
|
* scripttempl/aix.sc: Handle TLS sections.
|
||||||
|
* testsuite/ld-powerpc/aix52.exp: Add new tests.
|
||||||
|
* testsuite/ld-powerpc/aix-tls-reloc-32.d: New test.
|
||||||
|
* testsuite/ld-powerpc/aix-tls-reloc-64.d: New test.
|
||||||
|
* testsuite/ld-powerpc/aix-tls-reloc.ex: New test.
|
||||||
|
* testsuite/ld-powerpc/aix-tls-reloc.s: New test.
|
||||||
|
* testsuite/ld-powerpc/aix-tls-section-32.d: New test.
|
||||||
|
* testsuite/ld-powerpc/aix-tls-section-64.d: New test.
|
||||||
|
* testsuite/ld-powerpc/aix-tls-section.ex: New test.
|
||||||
|
* testsuite/ld-powerpc/aix-tls-section.s: New test.
|
||||||
|
|
||||||
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
2021-03-12 Clément Chigot <clement.chigot@atos.net>
|
||||||
|
|
||||||
* scripttempl/aix.sc: Add .te to .data section.
|
* scripttempl/aix.sc: Add .te to .data section.
|
||||||
|
@ -969,6 +969,44 @@ gld${EMULATION_NAME}_before_allocation (void)
|
|||||||
sec->flags |= SEC_KEEP;
|
sec->flags |= SEC_KEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure .tdata is removed if empty, even with -r flag.
|
||||||
|
.tdata is always being generated because its size is needed
|
||||||
|
to cumpute .data address. */
|
||||||
|
if (bfd_link_relocatable (&link_info))
|
||||||
|
{
|
||||||
|
static const char *const thread_sections[] = {
|
||||||
|
".tdata",
|
||||||
|
".tbss"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Run lang_size_sections (if not already done). */
|
||||||
|
if (expld.phase != lang_mark_phase_enum)
|
||||||
|
{
|
||||||
|
expld.phase = lang_mark_phase_enum;
|
||||||
|
expld.dataseg.phase = exp_seg_none;
|
||||||
|
one_lang_size_sections_pass (NULL, FALSE);
|
||||||
|
lang_reset_memory_regions ();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE (thread_sections); i++)
|
||||||
|
{
|
||||||
|
asection *sec;
|
||||||
|
|
||||||
|
sec = bfd_get_section_by_name (link_info.output_bfd,
|
||||||
|
thread_sections[i]);
|
||||||
|
|
||||||
|
if (sec != NULL && sec->rawsize == 0
|
||||||
|
&& (sec->flags & SEC_KEEP) == 0
|
||||||
|
&& !bfd_section_removed_from_list (link_info.output_bfd,
|
||||||
|
sec))
|
||||||
|
{
|
||||||
|
sec->flags |= SEC_EXCLUDE;
|
||||||
|
bfd_section_list_remove (link_info.output_bfd, sec);
|
||||||
|
link_info.output_bfd->section_count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
before_allocation_default ();
|
before_allocation_default ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,35 @@ SECTIONS
|
|||||||
${RELOCATING+PROVIDE (_etext = .);}
|
${RELOCATING+PROVIDE (_etext = .);}
|
||||||
}
|
}
|
||||||
|
|
||||||
. = ALIGN (ALIGN (0x10000000) + (. & 0xfff), 32);
|
/* .tdata and .tbss addresses are representing the offset from
|
||||||
|
the TLS pointer. It starts at -0x7800 for 64bit and -0x7c00
|
||||||
|
for 32bit.
|
||||||
|
TODO: 32bit should have -0x7c00 but it works like this for
|
||||||
|
now.
|
||||||
|
The other particularity is that they must be before .data
|
||||||
|
sections. But .data must be aligned correctly as if the
|
||||||
|
addresses were contiguous. This means that the correct
|
||||||
|
address must be restored, taking into account: the size of
|
||||||
|
.text, its alignment 2^5, the size of .tdata and its
|
||||||
|
aligment 2^4. */
|
||||||
|
.tdata -0x7800 : {
|
||||||
|
*(.tdata)
|
||||||
|
*(.tl)
|
||||||
|
}
|
||||||
|
|
||||||
|
.tbss : {
|
||||||
|
*(.tbss)
|
||||||
|
*(.ul)
|
||||||
|
}
|
||||||
|
|
||||||
|
. = ${RELOCATING+(ALIGN (0x10000000 + SIZEOF_HEADERS, 32)) + }SIZEOF(.text);
|
||||||
|
. = ALIGN (.,32);
|
||||||
|
. = . + SIZEOF(.tdata);
|
||||||
|
. = ALIGN (.,16);
|
||||||
|
|
||||||
|
/* .data starting address must be in a different segment than
|
||||||
|
the .text addresses. Thus, 0x10000000 is added. */
|
||||||
|
. = ALIGN (0x10000000) + (. & 0xfff);
|
||||||
.data . : {
|
.data . : {
|
||||||
${RELOCATING+PROVIDE (_data = .);}
|
${RELOCATING+PROVIDE (_data = .);}
|
||||||
*(.data)
|
*(.data)
|
||||||
|
35
ld/testsuite/ld-powerpc/aix-tls-reloc-32.d
Normal file
35
ld/testsuite/ld-powerpc/aix-tls-reloc-32.d
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#source: aix-tls-reloc.s
|
||||||
|
#as: -a32
|
||||||
|
#ld: -b32 -shared -bE:aix-tls-reloc.ex
|
||||||
|
#objdump: -dr
|
||||||
|
#target: [is_xcoff_format]
|
||||||
|
|
||||||
|
.*
|
||||||
|
|
||||||
|
Disassembly of section \.text:
|
||||||
|
|
||||||
|
.* <\.foo>:
|
||||||
|
.*: 80 82 00 00 l r4,0\(r2\)
|
||||||
|
.*: R_TOC gd-.*
|
||||||
|
.*: 80 62 00 04 l r3,4\(r2\)
|
||||||
|
.*: R_TOC .gd-.*
|
||||||
|
.*: 48 00 00 03 bla 0 <\.foo-.*>
|
||||||
|
.*: R_BA_26 __tls_get_addr
|
||||||
|
.*: 80 62 00 0c l r3,12\(r2\)
|
||||||
|
.*: R_TOC _\$TLSML-.*
|
||||||
|
.*: 48 00 00 03 bla 0 <\.foo-.*>
|
||||||
|
.*: R_BA_26 __tls_get_mod
|
||||||
|
.*: 80 82 00 08 l r4,8\(r2\)
|
||||||
|
.*: R_TOC ld-.*
|
||||||
|
.*: 7c a3 22 14 cax r5,r3,r4
|
||||||
|
.*: 48 00 00 03 bla 0 <\.foo-.*>
|
||||||
|
.*: R_BA_26 __get_tpointer
|
||||||
|
.*: 80 82 00 10 l r4,16\(r2\)
|
||||||
|
.*: R_TOC ie-.*
|
||||||
|
.*: 7c a3 22 14 cax r5,r3,r4
|
||||||
|
.*: 48 00 00 03 bla 0 <\.foo-.*>
|
||||||
|
.*: R_BA_26 __get_tpointer
|
||||||
|
.*: 80 82 00 14 l r4,20\(r2\)
|
||||||
|
.*: R_TOC le-.*
|
||||||
|
.*: 7c a3 22 14 cax r5,r3,r4
|
||||||
|
.*
|
31
ld/testsuite/ld-powerpc/aix-tls-reloc-64.d
Normal file
31
ld/testsuite/ld-powerpc/aix-tls-reloc-64.d
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#source: aix-tls-reloc.s
|
||||||
|
#as: -a32
|
||||||
|
#ld: -b32 -shared -bE:aix-tls-reloc.ex
|
||||||
|
#objdump: -dr
|
||||||
|
#target: [is_xcoff_format]
|
||||||
|
|
||||||
|
.*
|
||||||
|
|
||||||
|
Disassembly of section \.text:
|
||||||
|
|
||||||
|
.* <\.foo>:
|
||||||
|
.*: e8 82 00 00 ld r4,0\(r2\)
|
||||||
|
.*: R_TOC gd-.*
|
||||||
|
.*: e8 62 00 08 ld r3,8\(r2\)
|
||||||
|
.*: R_TOC .gd-.*
|
||||||
|
.*: 48 00 00 03 bla 0 <\.foo-.*>
|
||||||
|
.*: R_BA_26 __tls_get_addr
|
||||||
|
.*: e8 62 00 18 ld r3,24\(r2\)
|
||||||
|
.*: R_TOC _\$TLSML-.*
|
||||||
|
.*: 48 00 00 03 bla 0 <\.foo-.*>
|
||||||
|
.*: R_BA_26 __tls_get_mod
|
||||||
|
.*: 80 82 00 10 lwz r4,16\(r2\)
|
||||||
|
.*: R_TOC ld-.*
|
||||||
|
.*: 7c a3 22 14 add r5,r3,r4
|
||||||
|
.*: e8 82 00 20 ld r4,32\(r2\)
|
||||||
|
.*: R_TOC ie-.*
|
||||||
|
.*: 7c a4 6a 14 add r5,r4,r13
|
||||||
|
.*: e8 82 00 28 ld r4,40\(r2\)
|
||||||
|
.*: R_TOC le-.*
|
||||||
|
.*: 7c a3 6a 14 add r5,r3,r13
|
||||||
|
.*
|
1
ld/testsuite/ld-powerpc/aix-tls-reloc.ex
Normal file
1
ld/testsuite/ld-powerpc/aix-tls-reloc.ex
Normal file
@ -0,0 +1 @@
|
|||||||
|
foo
|
65
ld/testsuite/ld-powerpc/aix-tls-reloc.s
Normal file
65
ld/testsuite/ld-powerpc/aix-tls-reloc.s
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
.globl bar[TL]
|
||||||
|
.csect bar[TL]
|
||||||
|
.long 1
|
||||||
|
|
||||||
|
.toc
|
||||||
|
.tc gd[TC],bar[TL]
|
||||||
|
.tc .gd[TC],bar[TL]@m
|
||||||
|
.tc ld[TC],bar[TL]@ld
|
||||||
|
.tc mh[TC],mh[TC]@ml
|
||||||
|
.tc ie[TC],bar[TL]@ie
|
||||||
|
.tc le[TC],bar[TL]@le
|
||||||
|
|
||||||
|
.globl foo
|
||||||
|
.globl .foo
|
||||||
|
.csect foo[DS],3
|
||||||
|
foo:
|
||||||
|
.if size == 32
|
||||||
|
.long .foo, TOC[tc0], 0
|
||||||
|
.else
|
||||||
|
.llong .foo, TOC[tc0], 0
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.csect foo[PR]
|
||||||
|
.foo:
|
||||||
|
#GD
|
||||||
|
.if size == 32
|
||||||
|
lwz 4, gd[TC](2)
|
||||||
|
lwz 3, .gd[TC](2)
|
||||||
|
.else
|
||||||
|
ld 4, gd[TC](2)
|
||||||
|
ld 3, .gd[TC](2)
|
||||||
|
.endif
|
||||||
|
bla __tls_get_addr
|
||||||
|
|
||||||
|
#LD
|
||||||
|
.if size == 32
|
||||||
|
lwz 3, mh[TC](2)
|
||||||
|
.else
|
||||||
|
ld 3, mh[TC](2)
|
||||||
|
.endif
|
||||||
|
bla __tls_get_mod
|
||||||
|
lwz 4, ld[TC](2)
|
||||||
|
add 5,3,4
|
||||||
|
|
||||||
|
#IE
|
||||||
|
.if size == 32
|
||||||
|
bla __get_tpointer
|
||||||
|
lwz 4, ie[TC](2)
|
||||||
|
add 5,3,4
|
||||||
|
.else
|
||||||
|
ld 4, ie[TC](2)
|
||||||
|
add 5,4,13
|
||||||
|
.endif
|
||||||
|
|
||||||
|
#LE
|
||||||
|
.if size == 32
|
||||||
|
bla __get_tpointer
|
||||||
|
lwz 4, le[TC](2)
|
||||||
|
add 5,3,4
|
||||||
|
.else
|
||||||
|
ld 4, le[TC](2)
|
||||||
|
add 5,3,13
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.rename mh[TC], "_$TLSML" # Symbol for the module handle
|
15
ld/testsuite/ld-powerpc/aix-tls-section-32.d
Normal file
15
ld/testsuite/ld-powerpc/aix-tls-section-32.d
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#source: aix-tls-section.s
|
||||||
|
#as: -a32
|
||||||
|
#ld: -b32 -shared -bE:aix-tls-section.ex
|
||||||
|
#objdump: -hw
|
||||||
|
#target: [is_xcoff_format]
|
||||||
|
|
||||||
|
.*
|
||||||
|
|
||||||
|
Sections:
|
||||||
|
.*
|
||||||
|
0 \.text .* .* .* .* .* ALLOC, LOAD, CODE
|
||||||
|
1 \.tdata 00000008 ffff8800 ffff8800 .* .* CONTENTS, ALLOC, LOAD, DATA, THREAD_LOCAL
|
||||||
|
2 \.tbss 00000008 ffff8808 ffff8808 .* .* ALLOC, THREAD_LOCAL
|
||||||
|
3 \.data .* .* .* .* .* ALLOC, LOAD, DATA
|
||||||
|
#...
|
15
ld/testsuite/ld-powerpc/aix-tls-section-64.d
Normal file
15
ld/testsuite/ld-powerpc/aix-tls-section-64.d
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#source: aix-tls-section.s
|
||||||
|
#as: -a64
|
||||||
|
#ld: -b64 -shared -bE:aix-tls-section.ex
|
||||||
|
#objdump: -hw
|
||||||
|
#target: [is_xcoff_format]
|
||||||
|
|
||||||
|
.*
|
||||||
|
|
||||||
|
Sections\:
|
||||||
|
.*
|
||||||
|
0 \.text .* .* .* .* .* ALLOC, LOAD, CODE
|
||||||
|
1 \.tdata 00000008 ffffffffffff8800 ffffffffffff8800 .* .* CONTENTS, ALLOC, LOAD, DATA, THREAD_LOCAL
|
||||||
|
2 \.tbss 00000008 ffffffffffff8808 ffffffffffff8808 .* .* ALLOC, THREAD_LOCAL
|
||||||
|
3 \.data .* .* .* .* .* ALLOC, LOAD, DATA
|
||||||
|
#...
|
2
ld/testsuite/ld-powerpc/aix-tls-section.ex
Normal file
2
ld/testsuite/ld-powerpc/aix-tls-section.ex
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
foo
|
||||||
|
bar
|
8
ld/testsuite/ld-powerpc/aix-tls-section.s
Normal file
8
ld/testsuite/ld-powerpc/aix-tls-section.s
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* .tbss */
|
||||||
|
.comm foo[UL],8
|
||||||
|
.lcomm foo2_l,8,foo2[UL]
|
||||||
|
|
||||||
|
/* .tdata */
|
||||||
|
.globl bar[TL]
|
||||||
|
.csect bar[TL]
|
||||||
|
.long 1
|
@ -275,6 +275,16 @@ set aix7tests {
|
|||||||
"" {aix-largetoc-1.s}
|
"" {aix-largetoc-1.s}
|
||||||
{{objdump -dr aix-largetoc-1-SIZE.d}}
|
{{objdump -dr aix-largetoc-1-SIZE.d}}
|
||||||
"aix-largetoc-1.so"}
|
"aix-largetoc-1.so"}
|
||||||
|
|
||||||
|
{"TLS relocations" "-shared -bE:aix-tls-reloc.ex"
|
||||||
|
"" {aix-tls-reloc.s}
|
||||||
|
{{objdump -dr aix-tls-reloc-SIZE.d}}
|
||||||
|
"aix-tls-reloc.so"}
|
||||||
|
|
||||||
|
{"TLS section" "-shared -bE:aix-tls-section.ex"
|
||||||
|
"" {aix-tls-section.s}
|
||||||
|
{{objdump -hw aix-tls-section-SIZE.d}}
|
||||||
|
"aix-tls-section.so"}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach test $aix7tests {
|
foreach test $aix7tests {
|
||||||
|
Loading…
Reference in New Issue
Block a user