X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=ld%2Fldctor.c;h=830ec6e87e243f23a7ecf12ba84c9a879619a93c;hb=43e05cd4f48b550023819d823fec02abf54e26d3;hp=f9934fc22f5830b0b39e4e9d4090ae96e3ce936d;hpb=95c148b400bbaad77aeb0d067ed7c57a8eeb2ddc;p=binutils-gdb.git diff --git a/ld/ldctor.c b/ld/ldctor.c index f9934fc22f5..830ec6e87e2 100644 --- a/ld/ldctor.c +++ b/ld/ldctor.c @@ -1,29 +1,29 @@ /* ldctor.c -- constructor support routines - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1991-2021 Free Software Foundation, Inc. By Steve Chamberlain -This file is part of GLD, the Gnu Linker. + This file is part of the GNU Binutils. -GLD is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -GLD is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GLD; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "bfdlink.h" #include "safe-ctype.h" +#include "ctf-api.h" #include "ld.h" #include "ldexp.h" @@ -40,7 +40,7 @@ lang_statement_list_type constructor_list; /* Whether the constructors should be sorted. Note that this is global for the entire link; we assume that there is only a single CONSTRUCTORS command in the linker script. */ -bfd_boolean constructors_sorted; +bool constructors_sorted; /* The sets we have seen. */ struct set_info *sets; @@ -69,7 +69,7 @@ ldctor_add_set_entry (struct bfd_link_hash_entry *h, if (p == NULL) { - p = xmalloc (sizeof (struct set_info)); + p = (struct set_info *) xmalloc (sizeof (struct set_info)); p->next = sets; sets = p; p->h = h; @@ -81,37 +81,37 @@ ldctor_add_set_entry (struct bfd_link_hash_entry *h, { if (p->reloc != reloc) { - einfo (_("%P%X: Different relocs used in set %s\n"), + einfo (_("%X%P: different relocs used in set %s\n"), h->root.string); return; } /* Don't permit a set to be constructed from different object - file formats. The same reloc may have different results. We - actually could sometimes handle this, but the case is - unlikely to ever arise. Sometimes constructor symbols are in - unusual sections, such as the absolute section--this appears - to be the case in Linux a.out--and in such cases we just - assume everything is OK. */ + file formats. The same reloc may have different results. We + actually could sometimes handle this, but the case is + unlikely to ever arise. Sometimes constructor symbols are in + unusual sections, such as the absolute section--this appears + to be the case in Linux a.out--and in such cases we just + assume everything is OK. */ if (p->elements != NULL && section->owner != NULL && p->elements->section->owner != NULL && strcmp (bfd_get_target (section->owner), bfd_get_target (p->elements->section->owner)) != 0) { - einfo (_("%P%X: Different object file formats composing set %s\n"), + einfo (_("%X%P: different object file formats composing set %s\n"), h->root.string); return; } } - e = xmalloc (sizeof (struct set_element)); - e->next = NULL; + e = (struct set_element *) xmalloc (sizeof (struct set_element)); + e->u.next = NULL; e->name = name; e->section = section; e->value = value; - for (epp = &p->elements; *epp != NULL; epp = &(*epp)->next) + for (epp = &p->elements; *epp != NULL; epp = &(*epp)->u.next) ; *epp = e; @@ -131,7 +131,7 @@ ctor_prio (const char *name) while (*name == '_') ++name; - if (strncmp (name, "GLOBAL_", sizeof "GLOBAL_" - 1) != 0) + if (!startswith (name, "GLOBAL_")) return -1; name += sizeof "GLOBAL_" - 1; @@ -140,7 +140,7 @@ ctor_prio (const char *name) return -1; if (name[1] != 'I' && name[1] != 'D') return -1; - if (! ISDIGIT (name[3])) + if (!ISDIGIT (name[3])) return -1; return atoi (name + 3); @@ -152,17 +152,17 @@ ctor_prio (const char *name) static int ctor_cmp (const void *p1, const void *p2) { - const struct set_element * const *pe1 = p1; - const struct set_element * const *pe2 = p2; + const struct set_element *pe1 = *(const struct set_element **) p1; + const struct set_element *pe2 = *(const struct set_element **) p2; const char *n1; const char *n2; int prio1; int prio2; - n1 = (*pe1)->name; + n1 = pe1->name; if (n1 == NULL) n1 = ""; - n2 = (*pe2)->name; + n2 = pe2->name; if (n2 == NULL) n2 = ""; @@ -176,17 +176,15 @@ ctor_cmp (const void *p1, const void *p2) /* We sort in reverse order because that is what g++ expects. */ if (prio1 < prio2) return 1; - else if (prio1 > prio2) + if (prio1 > prio2) return -1; /* Force a stable sort. */ - - if (pe1 < pe2) + if (pe1->u.idx < pe2->u.idx) return -1; - else if (pe1 > pe2) + if (pe1->u.idx > pe2->u.idx) return 1; - else - return 0; + return 0; } /* This function is called after the first phase of the link and @@ -197,38 +195,39 @@ ctor_cmp (const void *p1, const void *p2) void ldctor_build_sets (void) { - static bfd_boolean called; - lang_statement_list_type *old; - bfd_boolean header_printed; + static bool called; + bool header_printed; struct set_info *p; /* The emulation code may call us directly, but we only want to do this once. */ if (called) return; - called = TRUE; + called = true; if (constructors_sorted) { for (p = sets; p != NULL; p = p->next) { int c, i; - struct set_element *e; + struct set_element *e, *enext; struct set_element **array; if (p->elements == NULL) continue; c = 0; - for (e = p->elements; e != NULL; e = e->next) + for (e = p->elements; e != NULL; e = e->u.next) ++c; - array = xmalloc (c * sizeof *array); + array = (struct set_element **) xmalloc (c * sizeof *array); i = 0; - for (e = p->elements; e != NULL; e = e->next) + for (e = p->elements; e != NULL; e = enext) { array[i] = e; + enext = e->u.next; + e->u.idx = i; ++i; } @@ -237,19 +236,17 @@ ldctor_build_sets (void) e = array[0]; p->elements = e; for (i = 0; i < c - 1; i++) - array[i]->next = array[i + 1]; - array[i]->next = NULL; + array[i]->u.next = array[i + 1]; + array[i]->u.next = NULL; free (array); } } - old = stat_ptr; - stat_ptr = &constructor_list; + lang_list_init (&constructor_list); + push_stat_ptr (&constructor_list); - lang_list_init (stat_ptr); - - header_printed = FALSE; + header_printed = false; for (p = sets; p != NULL; p = p->next) { struct set_element *e; @@ -273,13 +270,13 @@ ldctor_build_sets (void) except that we use the right size instead of .long. When generating relocatable output, we generate relocs instead of addresses. */ - howto = bfd_reloc_type_lookup (output_bfd, p->reloc); + howto = bfd_reloc_type_lookup (link_info.output_bfd, p->reloc); if (howto == NULL) { - if (link_info.relocatable) + if (bfd_link_relocatable (&link_info)) { - einfo (_("%P%X: %s does not support reloc %s for set %s\n"), - bfd_get_target (output_bfd), + einfo (_("%X%P: %s does not support reloc %s for set %s\n"), + bfd_get_target (link_info.output_bfd), bfd_get_reloc_code_name (p->reloc), p->h->root.string); continue; @@ -292,10 +289,17 @@ ldctor_build_sets (void) p->reloc); if (howto == NULL) { - einfo (_("%P%X: %s does not support reloc %s for set %s\n"), - bfd_get_target (p->elements->section->owner), - bfd_get_reloc_code_name (p->reloc), - p->h->root.string); + /* See PR 20911 for a reproducer. */ + if (p->elements->section->owner == NULL) + einfo (_("%X%P: special section %s does not support reloc %s for set %s\n"), + bfd_section_name (p->elements->section), + bfd_get_reloc_code_name (p->reloc), + p->h->root.string); + else + einfo (_("%X%P: %s does not support reloc %s for set %s\n"), + bfd_get_target (p->elements->section->owner), + bfd_get_reloc_code_name (p->reloc), + p->h->root.string); continue; } } @@ -313,29 +317,31 @@ ldctor_build_sets (void) size = QUAD; break; default: - einfo (_("%P%X: Unsupported size %d for set %s\n"), + einfo (_("%X%P: unsupported size %d for set %s\n"), bfd_get_reloc_size (howto), p->h->root.string); size = LONG; break; } - lang_add_assignment (exp_assop ('=', ".", - exp_unop (ALIGN_K, - exp_intop (reloc_size)))); - lang_add_assignment (exp_assop ('=', p->h->root.string, - exp_nameop (NAME, "."))); + lang_add_assignment (exp_assign (".", + exp_unop (ALIGN_K, + exp_intop (reloc_size)), + false)); + lang_add_assignment (exp_assign (p->h->root.string, + exp_nameop (NAME, "."), + false)); lang_add_data (size, exp_intop (p->count)); - for (e = p->elements; e != NULL; e = e->next) + for (e = p->elements; e != NULL; e = e->u.next) { if (config.map_file != NULL) { int len; - if (! header_printed) + if (!header_printed) { minfo (_("\nSet Symbol\n\n")); - header_printed = TRUE; + header_printed = true; } minfo ("%s", p->h->root.string); @@ -353,16 +359,16 @@ ldctor_build_sets (void) } if (e->name != NULL) - minfo ("%T\n", e->name); + minfo ("%pT\n", e->name); else minfo ("%G\n", e->section->owner, e->section, e->value); } /* Need SEC_KEEP for --gc-sections. */ - if (! bfd_is_abs_section (e->section)) + if (!bfd_is_abs_section (e->section)) e->section->flags |= SEC_KEEP; - if (link_info.relocatable) + if (bfd_link_relocatable (&link_info)) lang_add_reloc (p->reloc, howto, e->section, e->name, exp_intop (e->value)); else @@ -372,5 +378,5 @@ ldctor_build_sets (void) lang_add_data (size, exp_intop (0)); } - stat_ptr = old; + pop_stat_ptr (); }