/* linker.c -- BFD linker routines
- Copyright (C) 1993-2019 Free Software Foundation, Inc.
+ Copyright (C) 1993-2021 Free Software Foundation, Inc.
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
This file is part of BFD, the Binary File Descriptor library.
file at the end of <<NAME(aout,final_link)>>.
*/
-static bfd_boolean generic_link_add_object_symbols
+static bool generic_link_add_object_symbols
(bfd *, struct bfd_link_info *);
-static bfd_boolean generic_link_check_archive_element
+static bool generic_link_check_archive_element
(bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
- bfd_boolean *);
-static bfd_boolean generic_link_add_symbol_list
+ bool *);
+static bool generic_link_add_symbol_list
(bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **);
-static bfd_boolean generic_add_output_symbol
+static bool generic_add_output_symbol
(bfd *, size_t *psymalloc, asymbol *);
-static bfd_boolean default_data_link_order
+static bool default_data_link_order
(bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *);
-static bfd_boolean default_indirect_link_order
+static bool default_indirect_link_order
(bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *,
- bfd_boolean);
+ bool);
/* The link hash table structure is defined in bfdlink.h. It provides
a base hash table which the backend specific hash tables are built
/* Initialize a link hash table. The BFD argument is the one
responsible for creating this table. */
-bfd_boolean
+bool
_bfd_link_hash_table_init
(struct bfd_link_hash_table *table,
bfd *abfd ATTRIBUTE_UNUSED,
const char *),
unsigned int entsize)
{
- bfd_boolean ret;
+ bool ret;
BFD_ASSERT (!abfd->is_linker_output && !abfd->link.hash);
table->undefs = NULL;
/* Arrange for destruction of this hash table on closing ABFD. */
table->hash_table_free = _bfd_generic_link_hash_table_free;
abfd->link.hash = table;
- abfd->is_linker_output = TRUE;
+ abfd->is_linker_output = true;
}
return ret;
}
struct bfd_link_hash_entry *
bfd_link_hash_lookup (struct bfd_link_hash_table *table,
const char *string,
- bfd_boolean create,
- bfd_boolean copy,
- bfd_boolean follow)
+ bool create,
+ bool copy,
+ bool follow)
{
struct bfd_link_hash_entry *ret;
bfd_wrapped_link_hash_lookup (bfd *abfd,
struct bfd_link_info *info,
const char *string,
- bfd_boolean create,
- bfd_boolean copy,
- bfd_boolean follow)
+ bool create,
+ bool copy,
+ bool follow)
{
- bfd_size_type amt;
+ size_t amt;
if (info->wrap_hash != NULL)
{
#undef WRAP
#define WRAP "__wrap_"
- if (bfd_hash_lookup (info->wrap_hash, l, FALSE, FALSE) != NULL)
+ if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL)
{
char *n;
struct bfd_link_hash_entry *h;
n[1] = '\0';
strcat (n, WRAP);
strcat (n, l);
- h = bfd_link_hash_lookup (info->hash, n, create, TRUE, follow);
+ h = bfd_link_hash_lookup (info->hash, n, create, true, follow);
free (n);
return h;
}
#define REAL "__real_"
if (*l == '_'
- && CONST_STRNEQ (l, REAL)
+ && startswith (l, REAL)
&& bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1,
- FALSE, FALSE) != NULL)
+ false, false) != NULL)
{
char *n;
struct bfd_link_hash_entry *h;
n[0] = prefix;
n[1] = '\0';
strcat (n, l + sizeof REAL - 1);
- h = bfd_link_hash_lookup (info->hash, n, create, TRUE, follow);
+ h = bfd_link_hash_lookup (info->hash, n, create, true, follow);
free (n);
return h;
}
|| *l == info->wrap_char)
++l;
- if (CONST_STRNEQ (l, WRAP))
+ if (startswith (l, WRAP))
{
l += sizeof WRAP - 1;
- if (bfd_hash_lookup (info->wrap_hash, l, FALSE, FALSE) != NULL)
+ if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL)
{
char save = 0;
if (l - (sizeof WRAP - 1) != h->root.string)
save = *l;
*(char *) l = *h->root.string;
}
- h = bfd_link_hash_lookup (info->hash, l, FALSE, FALSE, FALSE);
+ h = bfd_link_hash_lookup (info->hash, l, false, false, false);
if (save)
*(char *) l = save;
}
void
bfd_link_hash_traverse
(struct bfd_link_hash_table *htab,
- bfd_boolean (*func) (struct bfd_link_hash_entry *, void *),
+ bool (*func) (struct bfd_link_hash_entry *, void *),
void *info)
{
unsigned int i;
/* Set local fields. */
ret = (struct generic_link_hash_entry *) entry;
- ret->written = FALSE;
+ ret->written = false;
ret->sym = NULL;
}
_bfd_generic_link_hash_table_create (bfd *abfd)
{
struct generic_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct generic_link_hash_table);
+ size_t amt = sizeof (struct generic_link_hash_table);
ret = (struct generic_link_hash_table *) bfd_malloc (amt);
if (ret == NULL)
bfd_hash_table_free (&ret->root.table);
free (ret);
obfd->link.hash = NULL;
- obfd->is_linker_output = FALSE;
+ obfd->is_linker_output = false;
}
/* Grab the symbols for an object file when doing a generic link. We
the hash table pointing to different instances of the symbol
structure. */
-bfd_boolean
+bool
bfd_generic_link_read_symbols (bfd *abfd)
{
if (bfd_get_outsymbols (abfd) == NULL)
symsize = bfd_get_symtab_upper_bound (abfd);
if (symsize < 0)
- return FALSE;
- bfd_get_outsymbols (abfd) = (struct bfd_symbol **) bfd_alloc (abfd,
- symsize);
+ return false;
+ abfd->outsymbols = bfd_alloc (abfd, symsize);
if (bfd_get_outsymbols (abfd) == NULL && symsize != 0)
- return FALSE;
+ return false;
symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd));
if (symcount < 0)
- return FALSE;
- bfd_get_symcount (abfd) = symcount;
+ return false;
+ abfd->symcount = symcount;
}
- return TRUE;
+ return true;
}
\f
/* Indicate that we are only retrieving symbol values from this
/* Generic function to add symbols from an object file to the
global hash table. */
-bfd_boolean
+bool
_bfd_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
- bfd_boolean ret;
+ bool ret;
switch (bfd_get_format (abfd))
{
break;
default:
bfd_set_error (bfd_error_wrong_format);
- ret = FALSE;
+ ret = false;
}
return ret;
/* Add symbols from an object file to the global hash table. */
-static bfd_boolean
+static bool
generic_link_add_object_symbols (bfd *abfd,
struct bfd_link_info *info)
{
struct bfd_symbol **outsyms;
if (!bfd_generic_link_read_symbols (abfd))
- return FALSE;
+ return false;
symcount = _bfd_generic_link_get_symcount (abfd);
outsyms = _bfd_generic_link_get_symbols (abfd);
return generic_link_add_symbol_list (abfd, info, symcount, outsyms);
those symbols instead if it does so. CHECKFN should only return
FALSE if some sort of error occurs. */
-bfd_boolean
+bool
_bfd_generic_link_add_archive_symbols
(bfd *abfd,
struct bfd_link_info *info,
- bfd_boolean (*checkfn) (bfd *, struct bfd_link_info *,
- struct bfd_link_hash_entry *, const char *,
- bfd_boolean *))
+ bool (*checkfn) (bfd *, struct bfd_link_info *,
+ struct bfd_link_hash_entry *, const char *, bool *))
{
- bfd_boolean loop;
+ bool loop;
bfd_size_type amt;
unsigned char *included;
{
/* An empty archive is a special case. */
if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
- return TRUE;
+ return true;
bfd_set_error (bfd_error_no_armap);
- return FALSE;
+ return false;
}
amt = bfd_ardata (abfd)->symdef_count;
if (amt == 0)
- return TRUE;
+ return true;
amt *= sizeof (*included);
included = (unsigned char *) bfd_zmalloc (amt);
if (included == NULL)
- return FALSE;
+ return false;
do
{
carsym *arsym;
unsigned int indx;
file_ptr last_ar_offset = -1;
- bfd_boolean needed = FALSE;
+ bool needed = false;
bfd *element = NULL;
- loop = FALSE;
+ loop = false;
arsyms = bfd_ardata (abfd)->symdefs;
arsym_end = arsyms + bfd_ardata (abfd)->symdef_count;
for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++)
if (arsym->name == NULL)
goto error_return;
-
+
h = bfd_link_hash_lookup (info->hash, arsym->name,
- FALSE, FALSE, TRUE);
+ false, false, true);
if (h == NULL
&& info->pei386_auto_import
- && CONST_STRNEQ (arsym->name, "__imp_"))
+ && startswith (arsym->name, "__imp_"))
h = bfd_link_hash_lookup (info->hash, arsym->name + 6,
- FALSE, FALSE, TRUE);
+ false, false, true);
if (h == NULL)
continue;
while (arsyms[mark].file_offset == last_ar_offset);
if (undefs_tail != info->hash->undefs_tail)
- loop = TRUE;
+ loop = true;
}
}
} while (loop);
free (included);
- return TRUE;
+ return true;
error_return:
free (included);
- return FALSE;
+ return false;
}
\f
/* See if we should include an archive element. */
-static bfd_boolean
+static bool
generic_link_check_archive_element (bfd *abfd,
struct bfd_link_info *info,
struct bfd_link_hash_entry *h,
const char *name ATTRIBUTE_UNUSED,
- bfd_boolean *pneeded)
+ bool *pneeded)
{
asymbol **pp, **ppend;
- *pneeded = FALSE;
+ *pneeded = false;
if (!bfd_generic_link_read_symbols (abfd))
- return FALSE;
+ return false;
pp = _bfd_generic_link_get_symbols (abfd);
ppend = pp + _bfd_generic_link_get_symcount (abfd);
symbol (type bfd_link_hash_undefweak) is not considered to be
a reference when pulling files out of an archive. See the
SVR4 ABI, p. 4-27. */
- h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), FALSE,
- FALSE, TRUE);
+ h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false,
+ false, true);
if (h == NULL
|| (h->type != bfd_link_hash_undefined
&& h->type != bfd_link_hash_common))
/* P is not a common symbol, or an undefined reference was
created from outside BFD such as from a linker -u option.
This object file defines the symbol, so pull it in. */
- *pneeded = TRUE;
+ *pneeded = true;
if (!(*info->callbacks
->add_archive_element) (info, abfd, bfd_asymbol_name (p),
&abfd))
- return FALSE;
+ return false;
/* Potentially, the add_archive_element hook may have set a
substitute BFD for us. */
return bfd_link_add_symbols (abfd, info);
bfd_hash_allocate (&info->hash->table,
sizeof (struct bfd_link_hash_common_entry));
if (h->u.c.p == NULL)
- return FALSE;
+ return false;
size = bfd_asymbol_value (p);
h->u.c.size = size;
}
/* This archive element is not needed. */
- return TRUE;
+ return true;
}
/* Add the symbols from an object file to the global hash table. ABFD
is the object file. INFO is the linker information. SYMBOL_COUNT
is the number of symbols. SYMBOLS is the list of symbols. */
-static bfd_boolean
+static bool
generic_link_add_symbol_list (bfd *abfd,
struct bfd_link_info *info,
bfd_size_type symbol_count,
| BSF_GLOBAL
| BSF_CONSTRUCTOR
| BSF_WEAK)) != 0
- || bfd_is_und_section (bfd_get_section (p))
- || bfd_is_com_section (bfd_get_section (p))
- || bfd_is_ind_section (bfd_get_section (p)))
+ || bfd_is_und_section (bfd_asymbol_section (p))
+ || bfd_is_com_section (bfd_asymbol_section (p))
+ || bfd_is_ind_section (bfd_asymbol_section (p)))
{
const char *name;
const char *string;
bh = NULL;
if (! (_bfd_generic_link_add_one_symbol
- (info, abfd, name, p->flags, bfd_get_section (p),
- p->value, string, FALSE, FALSE, &bh)))
- return FALSE;
+ (info, abfd, name, p->flags, bfd_asymbol_section (p),
+ p->value, string, false, false, &bh)))
+ return false;
h = (struct generic_link_hash_entry *) bh;
/* If this is a constructor symbol, and the linker didn't do
if (info->output_bfd->xvec == abfd->xvec)
{
if (h->sym == NULL
- || (! bfd_is_und_section (bfd_get_section (p))
- && (! bfd_is_com_section (bfd_get_section (p))
- || bfd_is_und_section (bfd_get_section (h->sym)))))
+ || (! bfd_is_und_section (bfd_asymbol_section (p))
+ && (! bfd_is_com_section (bfd_asymbol_section (p))
+ || bfd_is_und_section (bfd_asymbol_section (h->sym)))))
{
h->sym = p;
/* BSF_OLD_COMMON is a hack to support COFF reloc
reading, and it should go away when the COFF
linker is switched to the new version. */
- if (bfd_is_com_section (bfd_get_section (p)))
+ if (bfd_is_com_section (bfd_asymbol_section (p)))
p->flags |= BSF_OLD_COMMON;
}
}
}
}
- return TRUE;
+ return true;
}
\f
/* We use a state table to deal with adding symbols from an object
/* current\prev new undef undefw def defw com indr warn */
/* UNDEF_ROW */ {UND, NOACT, UND, REF, REF, NOACT, REFC, WARNC },
/* UNDEFW_ROW */ {WEAK, NOACT, NOACT, REF, REF, NOACT, REFC, WARNC },
- /* DEF_ROW */ {DEF, DEF, DEF, MDEF, DEF, CDEF, MDEF, CYCLE },
+ /* DEF_ROW */ {DEF, DEF, DEF, MDEF, DEF, CDEF, MIND, CYCLE },
/* DEFW_ROW */ {DEFW, DEFW, DEFW, NOACT, NOACT, NOACT, NOACT, CYCLE },
/* COMMON_ROW */ {COM, COM, COM, CREF, COM, BIG, REFC, WARNC },
/* INDR_ROW */ {IND, IND, IND, MDEF, IND, CIND, MIND, CYCLE },
entry; if *HASHP is not NULL, the caller has already looked up
the hash table entry, and stored it in *HASHP. */
-bfd_boolean
+bool
_bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
bfd *abfd,
const char *name,
asection *section,
bfd_vma value,
const char *string,
- bfd_boolean copy,
- bfd_boolean collect,
+ bool copy,
+ bool collect,
struct bfd_link_hash_entry **hashp)
{
enum link_row row;
struct bfd_link_hash_entry *h;
struct bfd_link_hash_entry *inh = NULL;
- bfd_boolean cycle;
+ bool cycle;
BFD_ASSERT (section != NULL);
/* Create the indirect symbol here. This is for the benefit of
the plugin "notice" function.
STRING is the name of the symbol we want to indirect to. */
- inh = bfd_wrapped_link_hash_lookup (abfd, info, string, TRUE,
- copy, FALSE);
+ inh = bfd_wrapped_link_hash_lookup (abfd, info, string, true,
+ copy, false);
if (inh == NULL)
- return FALSE;
+ return false;
}
else if ((flags & BSF_WARNING) != 0)
row = WARN_ROW;
else
{
if (row == UNDEF_ROW || row == UNDEFW_ROW)
- h = bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, copy, FALSE);
+ h = bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false);
else
- h = bfd_link_hash_lookup (info->hash, name, TRUE, copy, FALSE);
+ h = bfd_link_hash_lookup (info->hash, name, true, copy, false);
if (h == NULL)
{
if (hashp != NULL)
*hashp = NULL;
- return FALSE;
+ return false;
}
}
if (info->notice_all
|| (info->notice_hash != NULL
- && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
+ && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL))
{
if (! (*info->callbacks->notice) (info, h, inh,
abfd, section, value, flags))
- return FALSE;
+ return false;
}
if (hashp != NULL)
/* Treat symbols defined by early linker script pass as undefined. */
if (h->ldscript_def)
prev = bfd_link_hash_undefined;
- cycle = FALSE;
+ cycle = false;
action = link_action[(int) row][prev];
switch (action)
{
s = name + 1;
while (*s == '_')
++s;
- if (s[0] == 'G' && CONST_STRNEQ (s, CONS_PREFIX))
+ if (s[0] == 'G' && startswith (s, CONS_PREFIX))
{
char c;
bfd_hash_allocate (&info->hash->table,
sizeof (struct bfd_link_hash_common_entry));
if (h->u.c.p == NULL)
- return FALSE;
+ return false;
h->u.c.size = value;
case MIND:
/* Multiple indirect symbols. This is OK if they both point
to the same symbol. */
+ if (h->u.i.link->type == bfd_link_hash_defweak)
+ {
+ /* It is also OK to redefine a symbol that indirects to
+ a weak definition. So for sym@ver -> sym@@ver where
+ sym@@ver is weak and we have a new strong sym@ver,
+ redefine sym@@ver. Of course if there exists
+ sym -> sym@@ver then this also redefines sym. */
+ h = h->u.i.link;
+ cycle = true;
+ break;
+ }
if (strcmp (h->u.i.link->root.string, string) == 0)
break;
/* Fall through. */
(_("%pB: indirect symbol `%s' to `%s' is a loop"),
abfd, name, string);
bfd_set_error (bfd_error_invalid_operation);
- return FALSE;
+ return false;
}
if (inh->type == bfd_link_hash_new)
{
/* ??? If inh->type == bfd_link_hash_undefweak this
converts inh to bfd_link_hash_undefined. */
row = UNDEF_ROW;
- cycle = TRUE;
+ cycle = true;
}
h->type = bfd_link_hash_indirect;
case CYCLE:
/* Try again with the referenced symbol. */
h = h->u.i.link;
- cycle = TRUE;
+ cycle = true;
break;
case REFC:
if (h->u.undef.next == NULL && info->hash->undefs_tail != h)
h->u.undef.next = h;
h = h->u.i.link;
- cycle = TRUE;
+ cycle = true;
break;
case WARN:
((*info->hash->table.newfunc)
(NULL, &info->hash->table, h->root.string)));
if (sub == NULL)
- return FALSE;
+ return false;
*sub = *h;
sub->type = bfd_link_hash_warning;
sub->u.i.link = h;
w = (char *) bfd_hash_allocate (&info->hash->table, len);
if (w == NULL)
- return FALSE;
+ return false;
memcpy (w, string, len);
sub->u.i.warning = w;
}
}
while (cycle);
- return TRUE;
+ return true;
}
\f
/* Generic final link routine. */
-bfd_boolean
+bool
_bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info)
{
bfd *sub;
size_t outsymalloc;
struct generic_write_global_symbol_info wginfo;
- bfd_get_outsymbols (abfd) = NULL;
- bfd_get_symcount (abfd) = 0;
+ abfd->outsymbols = NULL;
+ abfd->symcount = 0;
outsymalloc = 0;
/* Mark all sections which will be included in the output file. */
for (o = abfd->sections; o != NULL; o = o->next)
for (p = o->map_head.link_order; p != NULL; p = p->next)
if (p->type == bfd_indirect_link_order)
- p->u.indirect.section->linker_mark = TRUE;
+ p->u.indirect.section->linker_mark = true;
/* Build the output symbol table. */
for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc))
- return FALSE;
+ return false;
/* Accumulate the global symbols. */
wginfo.info = info;
shouldn't really need one, since we have SYMCOUNT, but some old
code still expects one. */
if (! generic_add_output_symbol (abfd, &outsymalloc, NULL))
- return FALSE;
+ return false;
if (bfd_link_relocatable (info))
{
relsize = bfd_get_reloc_upper_bound (input_bfd,
input_section);
if (relsize < 0)
- return FALSE;
+ return false;
relocs = (arelent **) bfd_malloc (relsize);
if (!relocs && relsize != 0)
- return FALSE;
+ return false;
symbols = _bfd_generic_link_get_symbols (input_bfd);
reloc_count = bfd_canonicalize_reloc (input_bfd,
input_section,
symbols);
free (relocs);
if (reloc_count < 0)
- return FALSE;
+ return false;
BFD_ASSERT ((unsigned long) reloc_count
== input_section->reloc_count);
o->reloc_count += reloc_count;
amt *= sizeof (arelent *);
o->orelocation = (struct reloc_cache_entry **) bfd_alloc (abfd, amt);
if (!o->orelocation)
- return FALSE;
+ return false;
o->flags |= SEC_RELOC;
/* Reset the count so that it can be used as an index
when putting in the output relocs. */
case bfd_section_reloc_link_order:
case bfd_symbol_reloc_link_order:
if (! _bfd_generic_reloc_link_order (abfd, info, o, p))
- return FALSE;
+ return false;
break;
case bfd_indirect_link_order:
- if (! default_indirect_link_order (abfd, info, o, p, TRUE))
- return FALSE;
+ if (! default_indirect_link_order (abfd, info, o, p, true))
+ return false;
break;
default:
if (! _bfd_default_link_order (abfd, info, o, p))
- return FALSE;
+ return false;
break;
}
}
}
- return TRUE;
+ return true;
}
/* Add an output symbol to the output BFD. */
-static bfd_boolean
+static bool
generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym)
{
if (bfd_get_symcount (output_bfd) >= *psymalloc)
amt *= sizeof (asymbol *);
newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd), amt);
if (newsyms == NULL)
- return FALSE;
- bfd_get_outsymbols (output_bfd) = newsyms;
+ return false;
+ output_bfd->outsymbols = newsyms;
}
- bfd_get_outsymbols (output_bfd) [bfd_get_symcount (output_bfd)] = sym;
+ output_bfd->outsymbols[output_bfd->symcount] = sym;
if (sym != NULL)
- ++ bfd_get_symcount (output_bfd);
+ ++output_bfd->symcount;
- return TRUE;
+ return true;
}
/* Handle the symbols for an input BFD. */
-bfd_boolean
+bool
_bfd_generic_link_output_symbols (bfd *output_bfd,
bfd *input_bfd,
struct bfd_link_info *info,
asymbol **sym_end;
if (!bfd_generic_link_read_symbols (input_bfd))
- return FALSE;
+ return false;
/* Create a filename symbol if we are supposed to. */
if (info->create_object_symbols_section != NULL)
newsym = bfd_make_empty_symbol (input_bfd);
if (!newsym)
- return FALSE;
- newsym->name = input_bfd->filename;
+ return false;
+ newsym->name = bfd_get_filename (input_bfd);
newsym->value = 0;
newsym->flags = BSF_LOCAL | BSF_FILE;
newsym->section = sec;
if (! generic_add_output_symbol (output_bfd, psymalloc,
newsym))
- return FALSE;
+ return false;
break;
}
{
asymbol *sym;
struct generic_link_hash_entry *h;
- bfd_boolean output;
+ bool output;
h = NULL;
sym = *sym_ptr;
| BSF_GLOBAL
| BSF_CONSTRUCTOR
| BSF_WEAK)) != 0
- || bfd_is_und_section (bfd_get_section (sym))
- || bfd_is_com_section (bfd_get_section (sym))
- || bfd_is_ind_section (bfd_get_section (sym)))
+ || bfd_is_und_section (bfd_asymbol_section (sym))
+ || bfd_is_com_section (bfd_asymbol_section (sym))
+ || bfd_is_ind_section (bfd_asymbol_section (sym)))
{
if (sym->udata.p != NULL)
h = (struct generic_link_hash_entry *) sym->udata.p;
the relocs in the output format being used. */
h = NULL;
}
- else if (bfd_is_und_section (bfd_get_section (sym)))
+ else if (bfd_is_und_section (bfd_asymbol_section (sym)))
h = ((struct generic_link_hash_entry *)
bfd_wrapped_link_hash_lookup (output_bfd, info,
bfd_asymbol_name (sym),
- FALSE, FALSE, TRUE));
+ false, false, true));
else
h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info),
bfd_asymbol_name (sym),
- FALSE, FALSE, TRUE);
+ false, false, true);
if (h != NULL)
{
}
}
- /* This switch is straight from the old code in
- write_file_locals in ldsym.c. */
- if (info->strip == strip_all
- || (info->strip == strip_some
- && bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym),
- FALSE, FALSE) == NULL))
- output = FALSE;
+ if ((sym->flags & BSF_KEEP) == 0
+ && (info->strip == strip_all
+ || (info->strip == strip_some
+ && bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym),
+ false, false) == NULL)))
+ output = false;
else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0)
{
/* If this symbol is marked as occurring now, rather
better way. */
if (bfd_asymbol_bfd (sym) == input_bfd
&& (sym->flags & BSF_NOT_AT_END) != 0)
- output = TRUE;
+ output = true;
else
- output = FALSE;
+ output = false;
}
+ else if ((sym->flags & BSF_KEEP) != 0)
+ output = true;
else if (bfd_is_ind_section (sym->section))
- output = FALSE;
+ output = false;
else if ((sym->flags & BSF_DEBUGGING) != 0)
{
if (info->strip == strip_none)
- output = TRUE;
+ output = true;
else
- output = FALSE;
+ output = false;
}
else if (bfd_is_und_section (sym->section)
|| bfd_is_com_section (sym->section))
- output = FALSE;
+ output = false;
else if ((sym->flags & BSF_LOCAL) != 0)
{
if ((sym->flags & BSF_WARNING) != 0)
- output = FALSE;
+ output = false;
else
{
switch (info->discard)
{
default:
case discard_all:
- output = FALSE;
+ output = false;
break;
case discard_sec_merge:
- output = TRUE;
+ output = true;
if (bfd_link_relocatable (info)
|| ! (sym->section->flags & SEC_MERGE))
break;
/* FALLTHROUGH */
case discard_l:
if (bfd_is_local_label (input_bfd, sym))
- output = FALSE;
+ output = false;
else
- output = TRUE;
+ output = true;
break;
case discard_none:
- output = TRUE;
+ output = true;
break;
}
}
else if ((sym->flags & BSF_CONSTRUCTOR))
{
if (info->strip != strip_all)
- output = TRUE;
+ output = true;
else
- output = FALSE;
+ output = false;
}
else if (sym->flags == 0
&& (sym->section->owner->flags & BFD_PLUGIN) != 0)
/* LTO doesn't set symbol information. We get here with the
generic linker for a symbol that was "common" but no longer
needs to be global. */
- output = FALSE;
+ output = false;
else
abort ();
if (!bfd_is_abs_section (sym->section)
&& bfd_section_removed_from_list (output_bfd,
sym->section->output_section))
- output = FALSE;
+ output = false;
if (output)
{
if (! generic_add_output_symbol (output_bfd, psymalloc, sym))
- return FALSE;
+ return false;
if (h != NULL)
- h->written = TRUE;
+ h->written = true;
}
}
- return TRUE;
+ return true;
}
/* Set the section and value of a generic BFD symbol based on a linker
/* Write out a global symbol, if it hasn't already been written out.
This is called for each symbol in the hash table. */
-bfd_boolean
+bool
_bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *h,
void *data)
{
asymbol *sym;
if (h->written)
- return TRUE;
+ return true;
- h->written = TRUE;
+ h->written = true;
if (wginfo->info->strip == strip_all
|| (wginfo->info->strip == strip_some
&& bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string,
- FALSE, FALSE) == NULL))
- return TRUE;
+ false, false) == NULL))
+ return true;
if (h->sym != NULL)
sym = h->sym;
{
sym = bfd_make_empty_symbol (wginfo->output_bfd);
if (!sym)
- return FALSE;
+ return false;
sym->name = h->root.root.string;
sym->flags = 0;
}
abort ();
}
- return TRUE;
+ return true;
}
/* Create a relocation. */
-bfd_boolean
+bool
_bfd_generic_reloc_link_order (bfd *abfd,
struct bfd_link_info *info,
asection *sec,
r = (arelent *) bfd_alloc (abfd, sizeof (arelent));
if (r == NULL)
- return FALSE;
+ return false;
r->address = link_order->offset;
r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc);
if (r->howto == 0)
{
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
/* Get the symbol to use for the relocation. */
h = ((struct generic_link_hash_entry *)
bfd_wrapped_link_hash_lookup (abfd, info,
link_order->u.reloc.p->u.name,
- FALSE, FALSE, TRUE));
+ false, false, true));
if (h == NULL
|| ! h->written)
{
(*info->callbacks->unattached_reloc)
(info, link_order->u.reloc.p->u.name, NULL, NULL, 0);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
r->sym_ptr_ptr = &h->sym;
}
bfd_size_type size;
bfd_reloc_status_type rstat;
bfd_byte *buf;
- bfd_boolean ok;
+ bool ok;
file_ptr loc;
size = bfd_get_reloc_size (r->howto);
buf = (bfd_byte *) bfd_zmalloc (size);
if (buf == NULL && size != 0)
- return FALSE;
+ return false;
rstat = _bfd_relocate_contents (r->howto, abfd,
(bfd_vma) link_order->u.reloc.p->addend,
buf);
(*info->callbacks->reloc_overflow)
(info, NULL,
(link_order->type == bfd_section_reloc_link_order
- ? bfd_section_name (abfd, link_order->u.reloc.p->u.section)
+ ? bfd_section_name (link_order->u.reloc.p->u.section)
: link_order->u.reloc.p->u.name),
r->howto->name, link_order->u.reloc.p->addend,
NULL, NULL, 0);
break;
}
- loc = link_order->offset * bfd_octets_per_byte (abfd);
+ loc = link_order->offset * bfd_octets_per_byte (abfd, sec);
ok = bfd_set_section_contents (abfd, sec, buf, loc, size);
free (buf);
if (! ok)
- return FALSE;
+ return false;
r->addend = 0;
}
sec->orelocation[sec->reloc_count] = r;
++sec->reloc_count;
- return TRUE;
+ return true;
}
\f
/* Allocate a new link_order for a section. */
struct bfd_link_order *
bfd_new_link_order (bfd *abfd, asection *section)
{
- bfd_size_type amt = sizeof (struct bfd_link_order);
+ size_t amt = sizeof (struct bfd_link_order);
struct bfd_link_order *new_lo;
new_lo = (struct bfd_link_order *) bfd_zalloc (abfd, amt);
the reloc_link_order types here, since they depend upon the details
of how the particular backends generates relocs. */
-bfd_boolean
+bool
_bfd_default_link_order (bfd *abfd,
struct bfd_link_info *info,
asection *sec,
abort ();
case bfd_indirect_link_order:
return default_indirect_link_order (abfd, info, sec, link_order,
- FALSE);
+ false);
case bfd_data_link_order:
return default_data_link_order (abfd, info, sec, link_order);
}
/* Default routine to handle a bfd_data_link_order. */
-static bfd_boolean
+static bool
default_data_link_order (bfd *abfd,
- struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
asection *sec,
struct bfd_link_order *link_order)
{
size_t fill_size;
bfd_byte *fill;
file_ptr loc;
- bfd_boolean result;
+ bool result;
BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0);
size = link_order->size;
if (size == 0)
- return TRUE;
+ return true;
fill = link_order->u.data.contents;
fill_size = link_order->u.data.size;
if (fill_size == 0)
{
- fill = abfd->arch_info->fill (size, bfd_big_endian (abfd),
+ fill = abfd->arch_info->fill (size, info->big_endian,
(sec->flags & SEC_CODE) != 0);
if (fill == NULL)
- return FALSE;
+ return false;
}
else if (fill_size < size)
{
bfd_byte *p;
fill = (bfd_byte *) bfd_malloc (size);
if (fill == NULL)
- return FALSE;
+ return false;
p = fill;
if (fill_size == 1)
memset (p, (int) link_order->u.data.contents[0], (size_t) size);
}
}
- loc = link_order->offset * bfd_octets_per_byte (abfd);
+ loc = link_order->offset * bfd_octets_per_byte (abfd, sec);
result = bfd_set_section_contents (abfd, sec, fill, loc, size);
if (fill != link_order->u.data.contents)
/* Default routine to handle a bfd_indirect_link_order. */
-static bfd_boolean
+static bool
default_indirect_link_order (bfd *output_bfd,
struct bfd_link_info *info,
asection *output_section,
struct bfd_link_order *link_order,
- bfd_boolean generic_linker)
+ bool generic_linker)
{
asection *input_section;
bfd *input_bfd;
input_section = link_order->u.indirect.section;
input_bfd = input_section->owner;
if (input_section->size == 0)
- return TRUE;
+ return true;
BFD_ASSERT (input_section->output_section == output_section);
BFD_ASSERT (input_section->output_offset == link_order->offset);
(_("attempt to do relocatable link with %s input and %s output"),
bfd_get_target (input_bfd), bfd_get_target (output_bfd));
bfd_set_error (bfd_error_wrong_format);
- return FALSE;
+ return false;
}
if (! generic_linker)
a specific linker, presumably because we are linking
different types of object files together. */
if (!bfd_generic_link_read_symbols (input_bfd))
- return FALSE;
+ return false;
/* Since we have been called by a specific linker, rather than
the generic linker, the values of the symbols will not be
| BSF_GLOBAL
| BSF_CONSTRUCTOR
| BSF_WEAK)) != 0
- || bfd_is_und_section (bfd_get_section (sym))
- || bfd_is_com_section (bfd_get_section (sym))
- || bfd_is_ind_section (bfd_get_section (sym)))
+ || bfd_is_und_section (bfd_asymbol_section (sym))
+ || bfd_is_com_section (bfd_asymbol_section (sym))
+ || bfd_is_ind_section (bfd_asymbol_section (sym)))
{
/* sym->udata may have been set by
generic_link_add_symbol_list. */
if (sym->udata.p != NULL)
h = (struct bfd_link_hash_entry *) sym->udata.p;
- else if (bfd_is_und_section (bfd_get_section (sym)))
+ else if (bfd_is_und_section (bfd_asymbol_section (sym)))
h = bfd_wrapped_link_hash_lookup (output_bfd, info,
bfd_asymbol_name (sym),
- FALSE, FALSE, TRUE);
+ false, false, true);
else
h = bfd_link_hash_lookup (info->hash,
bfd_asymbol_name (sym),
- FALSE, FALSE, TRUE);
+ false, false, true);
if (h != NULL)
set_symbol_from_hash (sym, h);
}
}
/* Output the section contents. */
- loc = input_section->output_offset * bfd_octets_per_byte (output_bfd);
+ loc = (input_section->output_offset
+ * bfd_octets_per_byte (output_bfd, output_section));
if (! bfd_set_section_contents (output_bfd, output_section,
new_contents, loc, input_section->size))
goto error_return;
- if (contents != NULL)
- free (contents);
- return TRUE;
+ free (contents);
+ return true;
error_return:
- if (contents != NULL)
- free (contents);
- return FALSE;
+ free (contents);
+ return false;
}
/* A little routine to count the number of relocs in a link_order
bfd_link_split_section
SYNOPSIS
- bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec);
+ bool bfd_link_split_section (bfd *abfd, asection *sec);
DESCRIPTION
Return nonzero if @var{sec} should be split during a
*/
-bfd_boolean
+bool
_bfd_generic_link_split_section (bfd *abfd ATTRIBUTE_UNUSED,
asection *sec ATTRIBUTE_UNUSED)
{
- return FALSE;
+ return false;
}
/*
bfd_section_already_linked
SYNOPSIS
- bfd_boolean bfd_section_already_linked (bfd *abfd,
- asection *sec,
- struct bfd_link_info *info);
+ bool bfd_section_already_linked (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *info);
DESCRIPTION
Check if @var{data} has been already linked during a reloceatable
void
bfd_section_already_linked_table_traverse
- (bfd_boolean (*func) (struct bfd_section_already_linked_hash_entry *,
- void *), void *info)
+ (bool (*func) (struct bfd_section_already_linked_hash_entry *, void *),
+ void *info)
{
bfd_hash_traverse (&_bfd_section_already_linked_table,
- (bfd_boolean (*) (struct bfd_hash_entry *,
- void *)) func,
+ (bool (*) (struct bfd_hash_entry *, void *)) func,
info);
}
{
return ((struct bfd_section_already_linked_hash_entry *)
bfd_hash_lookup (&_bfd_section_already_linked_table, name,
- TRUE, FALSE));
+ true, false));
}
-bfd_boolean
+bool
bfd_section_already_linked_table_insert
(struct bfd_section_already_linked_hash_entry *already_linked_list,
asection *sec)
l = (struct bfd_section_already_linked *)
bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l);
if (l == NULL)
- return FALSE;
+ return false;
l->sec = sec;
l->next = already_linked_list->entry;
already_linked_list->entry = l;
- return TRUE;
+ return true;
}
static struct bfd_hash_entry *
return &ret->root;
}
-bfd_boolean
+bool
bfd_section_already_linked_table_init (void)
{
return bfd_hash_table_init_n (&_bfd_section_already_linked_table,
/* Report warnings as appropriate for duplicate section SEC.
Return FALSE if we decide to keep SEC after all. */
-bfd_boolean
+bool
_bfd_handle_already_linked (asection *sec,
struct bfd_section_already_linked *l,
struct bfd_link_info *info)
&& (l->sec->owner->flags & BFD_PLUGIN) != 0)
{
l->sec = sec;
- return FALSE;
+ return false;
}
break;
(_("%pB: duplicate section `%pA' has different contents\n"),
sec->owner, sec);
- if (sec_contents)
- free (sec_contents);
- if (l_sec_contents)
- free (l_sec_contents);
+ free (sec_contents);
+ free (l_sec_contents);
}
break;
}
which we are really going to use. */
sec->output_section = bfd_abs_section_ptr;
sec->kept_section = l->sec;
- return TRUE;
+ return true;
}
/* This is used on non-ELF inputs. */
-bfd_boolean
+bool
_bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED,
asection *sec,
struct bfd_link_info *info)
struct bfd_section_already_linked_hash_entry *already_linked_list;
if ((sec->flags & SEC_LINK_ONCE) == 0)
- return FALSE;
+ return false;
/* The generic linker doesn't handle section groups. */
if ((sec->flags & SEC_GROUP) != 0)
- return FALSE;
+ return false;
/* FIXME: When doing a relocatable link, we may have trouble
copying relocations in other sections that refer to local symbols
into a single large link once section, which defeats the purpose
of having link once sections in the first place. */
- name = bfd_get_section_name (abfd, sec);
+ name = bfd_section_name (sec);
already_linked_list = bfd_section_already_linked_table_lookup (name);
/* This is the first section with this name. Record it. */
if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
- return FALSE;
+ return false;
}
/* Choose a neighbouring section to S in OBFD that will be output, or
/* Convert symbols in excluded output sections to use a kept section. */
-static bfd_boolean
+static bool
fix_syms (struct bfd_link_hash_entry *h, void *data)
{
bfd *obfd = (bfd *) data;
}
}
- return TRUE;
+ return true;
}
void
bfd_generic_define_common_symbol
SYNOPSIS
- bfd_boolean bfd_generic_define_common_symbol
+ bool bfd_generic_define_common_symbol
(bfd *output_bfd, struct bfd_link_info *info,
struct bfd_link_hash_entry *h);
.
*/
-bfd_boolean
+bool
bfd_generic_define_common_symbol (bfd *output_bfd,
struct bfd_link_info *info ATTRIBUTE_UNUSED,
struct bfd_link_hash_entry *h)
section = h->u.c.p->section;
/* Increase the size of the section to align the common symbol.
- The alignment must be a power of two. */
- alignment = bfd_octets_per_byte (output_bfd) << power_of_two;
+ The alignment must be a power of two. But if the section does
+ not have any alignment requirement then do not increase the
+ alignment unnecessarily. */
+ if (power_of_two)
+ alignment = bfd_octets_per_byte (output_bfd, section) << power_of_two;
+ else
+ alignment = 1;
BFD_ASSERT (alignment != 0 && (alignment & -alignment) == alignment);
section->size += alignment - 1;
section->size &= -alignment;
it is no longer a common section. */
section->flags |= SEC_ALLOC;
section->flags &= ~(SEC_IS_COMMON | SEC_HAS_CONTENTS);
- return TRUE;
+ return true;
}
/*
{
struct bfd_link_hash_entry *h;
- h = bfd_link_hash_lookup (info->hash, symbol, FALSE, FALSE, TRUE);
+ h = bfd_link_hash_lookup (info->hash, symbol, false, false, true);
if (h != NULL
+ && !h->ldscript_def
&& (h->type == bfd_link_hash_undefined
|| h->type == bfd_link_hash_undefweak))
{
SYNOPSIS
struct bfd_elf_version_tree * bfd_find_version_for_sym
(struct bfd_elf_version_tree *verdefs,
- const char *sym_name, bfd_boolean *hide);
+ const char *sym_name, bool *hide);
DESCRIPTION
Search an elf version script tree for symbol versioning
struct bfd_elf_version_tree *
bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs,
const char *sym_name,
- bfd_boolean *hide)
+ bool *hide)
{
struct bfd_elf_version_tree *t;
struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver;
if (local_ver != NULL)
{
- *hide = TRUE;
+ *hide = true;
return local_ver;
}
bfd_hide_sym_by_version
SYNOPSIS
- bfd_boolean bfd_hide_sym_by_version
+ bool bfd_hide_sym_by_version
(struct bfd_elf_version_tree *verdefs, const char *sym_name);
DESCRIPTION
*/
-bfd_boolean
+bool
bfd_hide_sym_by_version (struct bfd_elf_version_tree *verdefs,
const char *sym_name)
{
- bfd_boolean hidden = FALSE;
+ bool hidden = false;
bfd_find_version_for_sym (verdefs, sym_name, &hidden);
return hidden;
}
bfd_link_check_relocs
SYNOPSIS
- bfd_boolean bfd_link_check_relocs
+ bool bfd_link_check_relocs
(bfd *abfd, struct bfd_link_info *info);
DESCRIPTION
This is the external entry point to this code.
*/
-bfd_boolean
+bool
bfd_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
{
return BFD_SEND (abfd, _bfd_link_check_relocs, (abfd, info));
_bfd_generic_link_check_relocs
SYNOPSIS
- bfd_boolean _bfd_generic_link_check_relocs
+ bool _bfd_generic_link_check_relocs
(bfd *abfd, struct bfd_link_info *info);
DESCRIPTION
outside the BFD library.
*/
-bfd_boolean
+bool
_bfd_generic_link_check_relocs (bfd *abfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
- return TRUE;
+ return true;
}
/*
bfd_merge_private_bfd_data
SYNOPSIS
- bfd_boolean bfd_merge_private_bfd_data
+ bool bfd_merge_private_bfd_data
(bfd *ibfd, struct bfd_link_info *info);
DESCRIPTION
_bfd_generic_verify_endian_match
SYNOPSIS
- bfd_boolean _bfd_generic_verify_endian_match
+ bool _bfd_generic_verify_endian_match
(bfd *ibfd, struct bfd_link_info *info);
DESCRIPTION
TRUE for a match, otherwise returns FALSE and emits an error.
*/
-bfd_boolean
+bool
_bfd_generic_verify_endian_match (bfd *ibfd, struct bfd_link_info *info)
{
bfd *obfd = info->output_bfd;
_bfd_error_handler (_("%pB: compiled for a little endian system "
"and target is big endian"), ibfd);
bfd_set_error (bfd_error_wrong_format);
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
int
return 0;
}
-bfd_boolean
+bool
_bfd_nolink_bfd_relax_section (bfd *abfd,
asection *section ATTRIBUTE_UNUSED,
struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
- bfd_boolean *again ATTRIBUTE_UNUSED)
+ bool *again ATTRIBUTE_UNUSED)
{
return _bfd_bool_bfd_false_error (abfd);
}
struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
struct bfd_link_order *link_order ATTRIBUTE_UNUSED,
bfd_byte *data ATTRIBUTE_UNUSED,
- bfd_boolean relocatable ATTRIBUTE_UNUSED,
+ bool relocatable ATTRIBUTE_UNUSED,
asymbol **symbols ATTRIBUTE_UNUSED)
{
return (bfd_byte *) _bfd_ptr_bfd_null_error (abfd);
}
-bfd_boolean
+bool
_bfd_nolink_bfd_lookup_section_flags
(struct bfd_link_info *info ATTRIBUTE_UNUSED,
struct flag_info *flaginfo ATTRIBUTE_UNUSED,
return _bfd_bool_bfd_false_error (section->owner);
}
-bfd_boolean
+bool
_bfd_nolink_bfd_is_group_section (bfd *abfd,
const asection *sec ATTRIBUTE_UNUSED)
{
return _bfd_bool_bfd_false_error (abfd);
}
-bfd_boolean
+const char *
+_bfd_nolink_bfd_group_name (bfd *abfd,
+ const asection *sec ATTRIBUTE_UNUSED)
+{
+ return _bfd_ptr_bfd_null_error (abfd);
+}
+
+bool
_bfd_nolink_bfd_discard_group (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
{
return _bfd_bool_bfd_false_error (abfd);
{
}
-bfd_boolean
+bool
_bfd_nolink_bfd_link_split_section (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
{
return _bfd_bool_bfd_false_error (abfd);
}
-bfd_boolean
+bool
_bfd_nolink_section_already_linked (bfd *abfd,
asection *sec ATTRIBUTE_UNUSED,
struct bfd_link_info *info ATTRIBUTE_UNUSED)
return _bfd_bool_bfd_false_error (abfd);
}
-bfd_boolean
+bool
_bfd_nolink_bfd_define_common_symbol
(bfd *abfd,
struct bfd_link_info *info ATTRIBUTE_UNUSED,