175fd0b74Schristos /* ldctor.c -- constructor support routines
2*e992f068Schristos Copyright (C) 1991-2022 Free Software Foundation, Inc.
375fd0b74Schristos By Steve Chamberlain <sac@cygnus.com>
475fd0b74Schristos
575fd0b74Schristos This file is part of the GNU Binutils.
675fd0b74Schristos
775fd0b74Schristos This program is free software; you can redistribute it and/or modify
875fd0b74Schristos it under the terms of the GNU General Public License as published by
975fd0b74Schristos the Free Software Foundation; either version 3 of the License, or
1075fd0b74Schristos (at your option) any later version.
1175fd0b74Schristos
1275fd0b74Schristos This program is distributed in the hope that it will be useful,
1375fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1475fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1575fd0b74Schristos GNU General Public License for more details.
1675fd0b74Schristos
1775fd0b74Schristos You should have received a copy of the GNU General Public License
1875fd0b74Schristos along with this program; if not, write to the Free Software
1975fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2075fd0b74Schristos MA 02110-1301, USA. */
2175fd0b74Schristos
2275fd0b74Schristos #include "sysdep.h"
2375fd0b74Schristos #include "bfd.h"
2475fd0b74Schristos #include "bfdlink.h"
2575fd0b74Schristos #include "safe-ctype.h"
26012573ebSchristos #include "ctf-api.h"
2775fd0b74Schristos
2875fd0b74Schristos #include "ld.h"
2975fd0b74Schristos #include "ldexp.h"
3075fd0b74Schristos #include "ldlang.h"
3175fd0b74Schristos #include "ldmisc.h"
3275fd0b74Schristos #include <ldgram.h>
3375fd0b74Schristos #include "ldmain.h"
3475fd0b74Schristos #include "ldctor.h"
3575fd0b74Schristos
3675fd0b74Schristos /* The list of statements needed to handle constructors. These are
3775fd0b74Schristos invoked by the command CONSTRUCTORS in the linker script. */
3875fd0b74Schristos lang_statement_list_type constructor_list;
3975fd0b74Schristos
4075fd0b74Schristos /* Whether the constructors should be sorted. Note that this is
4175fd0b74Schristos global for the entire link; we assume that there is only a single
4275fd0b74Schristos CONSTRUCTORS command in the linker script. */
43*e992f068Schristos bool constructors_sorted;
4475fd0b74Schristos
4575fd0b74Schristos /* The sets we have seen. */
4675fd0b74Schristos struct set_info *sets;
4775fd0b74Schristos
4875fd0b74Schristos /* Add an entry to a set. H is the entry in the linker hash table.
4975fd0b74Schristos RELOC is the relocation to use for an entry in the set. SECTION
5075fd0b74Schristos and VALUE are the value to add. This is called during the first
5175fd0b74Schristos phase of the link, when we are still gathering symbols together.
5275fd0b74Schristos We just record the information now. The ldctor_build_sets
5375fd0b74Schristos function will construct the sets. */
5475fd0b74Schristos
5575fd0b74Schristos void
ldctor_add_set_entry(struct bfd_link_hash_entry * h,bfd_reloc_code_real_type reloc,const char * name,asection * section,bfd_vma value)5675fd0b74Schristos ldctor_add_set_entry (struct bfd_link_hash_entry *h,
5775fd0b74Schristos bfd_reloc_code_real_type reloc,
5875fd0b74Schristos const char *name,
5975fd0b74Schristos asection *section,
6075fd0b74Schristos bfd_vma value)
6175fd0b74Schristos {
6275fd0b74Schristos struct set_info *p;
6375fd0b74Schristos struct set_element *e;
6475fd0b74Schristos struct set_element **epp;
6575fd0b74Schristos
6675fd0b74Schristos for (p = sets; p != NULL; p = p->next)
6775fd0b74Schristos if (p->h == h)
6875fd0b74Schristos break;
6975fd0b74Schristos
7075fd0b74Schristos if (p == NULL)
7175fd0b74Schristos {
7275fd0b74Schristos p = (struct set_info *) xmalloc (sizeof (struct set_info));
7375fd0b74Schristos p->next = sets;
7475fd0b74Schristos sets = p;
7575fd0b74Schristos p->h = h;
7675fd0b74Schristos p->reloc = reloc;
7775fd0b74Schristos p->count = 0;
7875fd0b74Schristos p->elements = NULL;
7975fd0b74Schristos }
8075fd0b74Schristos else
8175fd0b74Schristos {
8275fd0b74Schristos if (p->reloc != reloc)
8375fd0b74Schristos {
84ede78133Schristos einfo (_("%X%P: different relocs used in set %s\n"),
8575fd0b74Schristos h->root.string);
8675fd0b74Schristos return;
8775fd0b74Schristos }
8875fd0b74Schristos
8975fd0b74Schristos /* Don't permit a set to be constructed from different object
9075fd0b74Schristos file formats. The same reloc may have different results. We
9175fd0b74Schristos actually could sometimes handle this, but the case is
9275fd0b74Schristos unlikely to ever arise. Sometimes constructor symbols are in
9375fd0b74Schristos unusual sections, such as the absolute section--this appears
9475fd0b74Schristos to be the case in Linux a.out--and in such cases we just
9575fd0b74Schristos assume everything is OK. */
9675fd0b74Schristos if (p->elements != NULL
9775fd0b74Schristos && section->owner != NULL
9875fd0b74Schristos && p->elements->section->owner != NULL
9975fd0b74Schristos && strcmp (bfd_get_target (section->owner),
10075fd0b74Schristos bfd_get_target (p->elements->section->owner)) != 0)
10175fd0b74Schristos {
102ede78133Schristos einfo (_("%X%P: different object file formats composing set %s\n"),
10375fd0b74Schristos h->root.string);
10475fd0b74Schristos return;
10575fd0b74Schristos }
10675fd0b74Schristos }
10775fd0b74Schristos
10875fd0b74Schristos e = (struct set_element *) xmalloc (sizeof (struct set_element));
109012573ebSchristos e->u.next = NULL;
11075fd0b74Schristos e->name = name;
11175fd0b74Schristos e->section = section;
11275fd0b74Schristos e->value = value;
11375fd0b74Schristos
114012573ebSchristos for (epp = &p->elements; *epp != NULL; epp = &(*epp)->u.next)
11575fd0b74Schristos ;
11675fd0b74Schristos *epp = e;
11775fd0b74Schristos
11875fd0b74Schristos ++p->count;
11975fd0b74Schristos }
12075fd0b74Schristos
12175fd0b74Schristos /* Get the priority of a g++ global constructor or destructor from the
12275fd0b74Schristos symbol name. */
12375fd0b74Schristos
12475fd0b74Schristos static int
ctor_prio(const char * name)12575fd0b74Schristos ctor_prio (const char *name)
12675fd0b74Schristos {
12775fd0b74Schristos /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
12875fd0b74Schristos There might be extra leading underscores, and the $ characters
12975fd0b74Schristos might be something else. The I might be a D. */
13075fd0b74Schristos
13175fd0b74Schristos while (*name == '_')
13275fd0b74Schristos ++name;
13375fd0b74Schristos
134*e992f068Schristos if (!startswith (name, "GLOBAL_"))
13575fd0b74Schristos return -1;
13675fd0b74Schristos
13775fd0b74Schristos name += sizeof "GLOBAL_" - 1;
13875fd0b74Schristos
13975fd0b74Schristos if (name[0] != name[2])
14075fd0b74Schristos return -1;
14175fd0b74Schristos if (name[1] != 'I' && name[1] != 'D')
14275fd0b74Schristos return -1;
14375fd0b74Schristos if (!ISDIGIT (name[3]))
14475fd0b74Schristos return -1;
14575fd0b74Schristos
14675fd0b74Schristos return atoi (name + 3);
14775fd0b74Schristos }
14875fd0b74Schristos
14975fd0b74Schristos /* This function is used to sort constructor elements by priority. It
15075fd0b74Schristos is called via qsort. */
15175fd0b74Schristos
15275fd0b74Schristos static int
ctor_cmp(const void * p1,const void * p2)15375fd0b74Schristos ctor_cmp (const void *p1, const void *p2)
15475fd0b74Schristos {
155012573ebSchristos const struct set_element *pe1 = *(const struct set_element **) p1;
156012573ebSchristos const struct set_element *pe2 = *(const struct set_element **) p2;
15775fd0b74Schristos const char *n1;
15875fd0b74Schristos const char *n2;
15975fd0b74Schristos int prio1;
16075fd0b74Schristos int prio2;
16175fd0b74Schristos
162012573ebSchristos n1 = pe1->name;
16375fd0b74Schristos if (n1 == NULL)
16475fd0b74Schristos n1 = "";
165012573ebSchristos n2 = pe2->name;
16675fd0b74Schristos if (n2 == NULL)
16775fd0b74Schristos n2 = "";
16875fd0b74Schristos
16975fd0b74Schristos /* We need to sort in reverse order by priority. When two
17075fd0b74Schristos constructors have the same priority, we should maintain their
17175fd0b74Schristos current relative position. */
17275fd0b74Schristos
17375fd0b74Schristos prio1 = ctor_prio (n1);
17475fd0b74Schristos prio2 = ctor_prio (n2);
17575fd0b74Schristos
17675fd0b74Schristos /* We sort in reverse order because that is what g++ expects. */
17775fd0b74Schristos if (prio1 < prio2)
17875fd0b74Schristos return 1;
179012573ebSchristos if (prio1 > prio2)
18075fd0b74Schristos return -1;
18175fd0b74Schristos
18275fd0b74Schristos /* Force a stable sort. */
183012573ebSchristos if (pe1->u.idx < pe2->u.idx)
18475fd0b74Schristos return -1;
185012573ebSchristos if (pe1->u.idx > pe2->u.idx)
18675fd0b74Schristos return 1;
18775fd0b74Schristos return 0;
18875fd0b74Schristos }
18975fd0b74Schristos
19075fd0b74Schristos /* This function is called after the first phase of the link and
19175fd0b74Schristos before the second phase. At this point all set information has
19275fd0b74Schristos been gathered. We now put the statements to build the sets
19375fd0b74Schristos themselves into constructor_list. */
19475fd0b74Schristos
19575fd0b74Schristos void
ldctor_build_sets(void)19675fd0b74Schristos ldctor_build_sets (void)
19775fd0b74Schristos {
198*e992f068Schristos static bool called;
199*e992f068Schristos bool header_printed;
20075fd0b74Schristos struct set_info *p;
20175fd0b74Schristos
20275fd0b74Schristos /* The emulation code may call us directly, but we only want to do
20375fd0b74Schristos this once. */
20475fd0b74Schristos if (called)
20575fd0b74Schristos return;
206*e992f068Schristos called = true;
20775fd0b74Schristos
20875fd0b74Schristos if (constructors_sorted)
20975fd0b74Schristos {
21075fd0b74Schristos for (p = sets; p != NULL; p = p->next)
21175fd0b74Schristos {
21275fd0b74Schristos int c, i;
213012573ebSchristos struct set_element *e, *enext;
21475fd0b74Schristos struct set_element **array;
21575fd0b74Schristos
21675fd0b74Schristos if (p->elements == NULL)
21775fd0b74Schristos continue;
21875fd0b74Schristos
21975fd0b74Schristos c = 0;
220012573ebSchristos for (e = p->elements; e != NULL; e = e->u.next)
22175fd0b74Schristos ++c;
22275fd0b74Schristos
22375fd0b74Schristos array = (struct set_element **) xmalloc (c * sizeof *array);
22475fd0b74Schristos
22575fd0b74Schristos i = 0;
226012573ebSchristos for (e = p->elements; e != NULL; e = enext)
22775fd0b74Schristos {
22875fd0b74Schristos array[i] = e;
229012573ebSchristos enext = e->u.next;
230012573ebSchristos e->u.idx = i;
23175fd0b74Schristos ++i;
23275fd0b74Schristos }
23375fd0b74Schristos
23475fd0b74Schristos qsort (array, c, sizeof *array, ctor_cmp);
23575fd0b74Schristos
23675fd0b74Schristos e = array[0];
23775fd0b74Schristos p->elements = e;
23875fd0b74Schristos for (i = 0; i < c - 1; i++)
239012573ebSchristos array[i]->u.next = array[i + 1];
240012573ebSchristos array[i]->u.next = NULL;
24175fd0b74Schristos
24275fd0b74Schristos free (array);
24375fd0b74Schristos }
24475fd0b74Schristos }
24575fd0b74Schristos
24675fd0b74Schristos lang_list_init (&constructor_list);
24775fd0b74Schristos push_stat_ptr (&constructor_list);
24875fd0b74Schristos
249*e992f068Schristos header_printed = false;
25075fd0b74Schristos for (p = sets; p != NULL; p = p->next)
25175fd0b74Schristos {
25275fd0b74Schristos struct set_element *e;
25375fd0b74Schristos reloc_howto_type *howto;
25475fd0b74Schristos int reloc_size, size;
25575fd0b74Schristos
25675fd0b74Schristos /* If the symbol is defined, we may have been invoked from
25775fd0b74Schristos collect, and the sets may already have been built, so we do
25875fd0b74Schristos not do anything. */
25975fd0b74Schristos if (p->h->type == bfd_link_hash_defined
26075fd0b74Schristos || p->h->type == bfd_link_hash_defweak)
26175fd0b74Schristos continue;
26275fd0b74Schristos
26375fd0b74Schristos /* For each set we build:
26475fd0b74Schristos set:
26575fd0b74Schristos .long number_of_elements
26675fd0b74Schristos .long element0
26775fd0b74Schristos ...
26875fd0b74Schristos .long elementN
26975fd0b74Schristos .long 0
27075fd0b74Schristos except that we use the right size instead of .long. When
27175fd0b74Schristos generating relocatable output, we generate relocs instead of
27275fd0b74Schristos addresses. */
27375fd0b74Schristos howto = bfd_reloc_type_lookup (link_info.output_bfd, p->reloc);
27475fd0b74Schristos if (howto == NULL)
27575fd0b74Schristos {
27675fd0b74Schristos if (bfd_link_relocatable (&link_info))
27775fd0b74Schristos {
278ede78133Schristos einfo (_("%X%P: %s does not support reloc %s for set %s\n"),
27975fd0b74Schristos bfd_get_target (link_info.output_bfd),
28075fd0b74Schristos bfd_get_reloc_code_name (p->reloc),
28175fd0b74Schristos p->h->root.string);
28275fd0b74Schristos continue;
28375fd0b74Schristos }
28475fd0b74Schristos
28575fd0b74Schristos /* If this is not a relocatable link, all we need is the
28675fd0b74Schristos size, which we can get from the input BFD. */
28775fd0b74Schristos if (p->elements->section->owner != NULL)
28875fd0b74Schristos howto = bfd_reloc_type_lookup (p->elements->section->owner,
28975fd0b74Schristos p->reloc);
29075fd0b74Schristos if (howto == NULL)
29175fd0b74Schristos {
292ede78133Schristos /* See PR 20911 for a reproducer. */
293ede78133Schristos if (p->elements->section->owner == NULL)
294ede78133Schristos einfo (_("%X%P: special section %s does not support reloc %s for set %s\n"),
295012573ebSchristos bfd_section_name (p->elements->section),
296ede78133Schristos bfd_get_reloc_code_name (p->reloc),
297ede78133Schristos p->h->root.string);
298ede78133Schristos else
299ede78133Schristos einfo (_("%X%P: %s does not support reloc %s for set %s\n"),
30075fd0b74Schristos bfd_get_target (p->elements->section->owner),
30175fd0b74Schristos bfd_get_reloc_code_name (p->reloc),
30275fd0b74Schristos p->h->root.string);
30375fd0b74Schristos continue;
30475fd0b74Schristos }
30575fd0b74Schristos }
30675fd0b74Schristos
30775fd0b74Schristos reloc_size = bfd_get_reloc_size (howto);
30875fd0b74Schristos switch (reloc_size)
30975fd0b74Schristos {
31075fd0b74Schristos case 1: size = BYTE; break;
31175fd0b74Schristos case 2: size = SHORT; break;
31275fd0b74Schristos case 4: size = LONG; break;
31375fd0b74Schristos case 8:
31475fd0b74Schristos if (howto->complain_on_overflow == complain_overflow_signed)
31575fd0b74Schristos size = SQUAD;
31675fd0b74Schristos else
31775fd0b74Schristos size = QUAD;
31875fd0b74Schristos break;
31975fd0b74Schristos default:
320ede78133Schristos einfo (_("%X%P: unsupported size %d for set %s\n"),
32175fd0b74Schristos bfd_get_reloc_size (howto), p->h->root.string);
32275fd0b74Schristos size = LONG;
32375fd0b74Schristos break;
32475fd0b74Schristos }
32575fd0b74Schristos
32675fd0b74Schristos lang_add_assignment (exp_assign (".",
32775fd0b74Schristos exp_unop (ALIGN_K,
32875fd0b74Schristos exp_intop (reloc_size)),
329*e992f068Schristos false));
33075fd0b74Schristos lang_add_assignment (exp_assign (p->h->root.string,
33175fd0b74Schristos exp_nameop (NAME, "."),
332*e992f068Schristos false));
33375fd0b74Schristos lang_add_data (size, exp_intop (p->count));
33475fd0b74Schristos
335012573ebSchristos for (e = p->elements; e != NULL; e = e->u.next)
33675fd0b74Schristos {
33775fd0b74Schristos if (config.map_file != NULL)
33875fd0b74Schristos {
33975fd0b74Schristos int len;
34075fd0b74Schristos
34175fd0b74Schristos if (!header_printed)
34275fd0b74Schristos {
34375fd0b74Schristos minfo (_("\nSet Symbol\n\n"));
344*e992f068Schristos header_printed = true;
34575fd0b74Schristos }
34675fd0b74Schristos
34775fd0b74Schristos minfo ("%s", p->h->root.string);
34875fd0b74Schristos len = strlen (p->h->root.string);
34975fd0b74Schristos
35075fd0b74Schristos if (len >= 19)
35175fd0b74Schristos {
35275fd0b74Schristos print_nl ();
35375fd0b74Schristos len = 0;
35475fd0b74Schristos }
35575fd0b74Schristos while (len < 20)
35675fd0b74Schristos {
35775fd0b74Schristos print_space ();
35875fd0b74Schristos ++len;
35975fd0b74Schristos }
36075fd0b74Schristos
36175fd0b74Schristos if (e->name != NULL)
362ede78133Schristos minfo ("%pT\n", e->name);
36375fd0b74Schristos else
36475fd0b74Schristos minfo ("%G\n", e->section->owner, e->section, e->value);
36575fd0b74Schristos }
36675fd0b74Schristos
36775fd0b74Schristos /* Need SEC_KEEP for --gc-sections. */
36875fd0b74Schristos if (!bfd_is_abs_section (e->section))
36975fd0b74Schristos e->section->flags |= SEC_KEEP;
37075fd0b74Schristos
37175fd0b74Schristos if (bfd_link_relocatable (&link_info))
37275fd0b74Schristos lang_add_reloc (p->reloc, howto, e->section, e->name,
37375fd0b74Schristos exp_intop (e->value));
37475fd0b74Schristos else
37575fd0b74Schristos lang_add_data (size, exp_relop (e->section, e->value));
37675fd0b74Schristos }
37775fd0b74Schristos
37875fd0b74Schristos lang_add_data (size, exp_intop (0));
37975fd0b74Schristos }
38075fd0b74Schristos
38175fd0b74Schristos pop_stat_ptr ();
38275fd0b74Schristos }
383