static bfd_boolean
gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry)
{
- if (!entry->as_needed
- || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0)
- return FALSE;
+ int class = 0;
/* Tell the ELF linker that we don't want the output file to have a
DT_NEEDED entry for this file, unless it is used to resolve
references in a regular object. */
- bfd_elf_set_dyn_lib_class (entry->the_bfd, DYN_AS_NEEDED);
+ if (entry->as_needed)
+ class = DYN_AS_NEEDED;
+
+ /* Tell the ELF linker that we don't want the output file to have a
+ DT_NEEDED entry for any dynamic library in DT_NEEDED tags from
+ this file at all. */
+ if (!entry->add_needed)
+ class |= DYN_NO_ADD_NEEDED;
+
+ if (!class
+ || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0)
+ return FALSE;
+
+ bfd_elf_set_dyn_lib_class (entry->the_bfd, class);
/* Continue on with normal load_symbols processing. */
return FALSE;
global_needed->name, global_needed->by, soname);
}
+struct dt_needed
+{
+ bfd *by;
+ const char *name;
+};
/* This function is called for each possible name for a dynamic object
named by a DT_NEEDED entry. The FORCE parameter indicates whether
to skip the check for a conflicting version. */
static bfd_boolean
-gld${EMULATION_NAME}_try_needed (const char *name, int force)
+gld${EMULATION_NAME}_try_needed (struct dt_needed *needed,
+ int force)
{
bfd *abfd;
+ const char *name = needed->name;
const char *soname;
+ int class;
abfd = bfd_openr (name, bfd_get_target (output_bfd));
if (abfd == NULL)
/* Tell the ELF linker that we don't want the output file to have a
DT_NEEDED entry for this file, unless it is used to resolve
references in a regular object. */
- bfd_elf_set_dyn_lib_class (abfd, DYN_DT_NEEDED);
+ class = DYN_DT_NEEDED;
+
+ /* Tell the ELF linker that we don't want the output file to have a
+ DT_NEEDED entry for this file at all if the entry is from a file
+ with DYN_NO_ADD_NEEDED. */
+ if (needed->by
+ && (bfd_elf_get_dyn_lib_class (needed->by)
+ & DYN_NO_ADD_NEEDED) != 0)
+ class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED;
+
+ bfd_elf_set_dyn_lib_class (abfd, class);
/* Add this file into the symbol table. */
if (! bfd_link_add_symbols (abfd, &link_info))
/* Search for a needed file in a path. */
static bfd_boolean
-gld${EMULATION_NAME}_search_needed (const char *path, const char *name, int force)
+gld${EMULATION_NAME}_search_needed (const char *path,
+ struct dt_needed *n, int force)
{
const char *s;
+ const char *name = n->name;
size_t len;
+ struct dt_needed needed;
if (name[0] == '/')
- return gld${EMULATION_NAME}_try_needed (name, force);
+ return gld${EMULATION_NAME}_try_needed (n, force);
if (path == NULL || *path == '\0')
return FALSE;
+
+ needed.by = n->by;
+ needed.name = n->name;
+
len = strlen (name);
while (1)
{
}
strcpy (sset, name);
- if (gld${EMULATION_NAME}_try_needed (filename, force))
+ needed.name = filename;
+ if (gld${EMULATION_NAME}_try_needed (&needed, force))
return TRUE;
free (filename);
{
static bfd_boolean initialized;
static char *ld_so_conf;
+ struct dt_needed needed;
if (! initialized)
{
if (ld_so_conf == NULL)
return FALSE;
- return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force);
+
+ needed.by = NULL;
+ needed.name = name;
+ return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force);
}
EOF
for (l = needed; l != NULL; l = l->next)
{
struct bfd_link_needed_list *ll;
+ struct dt_needed n, nn;
int force;
/* If we've already seen this file, skip it. */
if (global_found)
continue;
+ n.by = l->by;
+ n.name = l->name;
+ nn.by = l->by;
if (trace_file_tries)
info_msg (_("%s needed by %B\n"), l->name, l->by);
cat >>e${EMULATION_NAME}.c <<EOF
if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
- l->name, force))
+ &n, force))
break;
EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
cat >>e${EMULATION_NAME}.c <<EOF
if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
- l->name, force))
+ &n, force))
break;
EOF
fi
&& command_line.rpath == NULL)
{
lib_path = (const char *) getenv ("LD_RUN_PATH");
- if (gld${EMULATION_NAME}_search_needed (lib_path, l->name,
+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
force))
break;
}
lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
- if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force))
+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force))
break;
EOF
fi
char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name);
found = (rp->by == l->by
&& gld${EMULATION_NAME}_search_needed (tmpname,
- l->name,
+ &n,
force));
free (tmpname);
}
continue;
filename = (char *) xmalloc (strlen (search->name) + len + 2);
sprintf (filename, "%s/%s", search->name, l->name);
- if (gld${EMULATION_NAME}_try_needed (filename, force))
+ nn.name = filename;
+ if (gld${EMULATION_NAME}_try_needed (&nn, force))
break;
free (filename);
}
if (sinterp != NULL)
{
sinterp->contents = ${ELF_INTERPRETER_NAME};
- sinterp->_raw_size = strlen (sinterp->contents) + 1;
+ sinterp->size = strlen (sinterp->contents) + 1;
}
"
&& sinterp != NULL)
{
sinterp->contents = (bfd_byte *) command_line.interpreter;
- sinterp->_raw_size = strlen (command_line.interpreter) + 1;
+ sinterp->size = strlen (command_line.interpreter) + 1;
}
/* Look for any sections named .gnu.warning. As a GNU extensions,
if (s == NULL)
continue;
- sz = bfd_section_size (is->the_bfd, s);
+ sz = s->size;
prefix_len = strlen (gnu_warning_prefix);
msg = xmalloc ((size_t) (prefix_len + sz + 1));
strcpy (msg, gnu_warning_prefix);
/* Clobber the section size, so that we don't waste copying the
warning into the output file. */
- s->_raw_size = 0;
+ s->size = 0;
}
}
}
lang_statement_union_type **os_tail;
etree_type *load_base;
int isdyn = 0;
+ asection *sec;
secname = bfd_get_section_name (s->owner, s);
+
if (! link_info.relocatable
&& link_info.combreloc
&& (s->flags & SEC_ALLOC)
#define HAVE_SECTION(hold, name) \
(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
- if (link_info.relocatable && (s->flags & SEC_DEBUGGING) == 0)
- s->flags &= ~SEC_EXCLUDE;
-
- if ((s->flags & SEC_EXCLUDE) != 0)
- {
- if (s->output_section == NULL)
- s->output_section = bfd_abs_section_ptr;
- return TRUE;
- }
-
place = NULL;
if ((s->flags & SEC_ALLOC) == 0)
;
/* Choose a unique name for the section. This will be needed if the
same section name appears in the input file with different
- loadable or allocatable characteristics. */
- if (bfd_get_section_by_name (output_bfd, secname) != NULL)
+ loadable or allocatable characteristics. But if the section
+ already exists but does not have any flags set, then it has been
+ created by the linker, probably as a result of a --section-start
+ command line switch. */
+ if ((sec = bfd_get_section_by_name (output_bfd, secname)) != NULL
+ && bfd_get_section_flags (output_bfd, sec) != 0)
{
secname = bfd_get_unique_section_name (output_bfd, secname, &count);
if (secname == NULL)