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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#define TARGET_IS_${EMULATION_NAME}
+#include "config.h"
#include "bfd.h"
#include "sysdep.h"
#include "libiberty.h"
#include "ldemul.h"
#include <ldgram.h>
#include "elf/common.h"
+#include "elf-bfd.h"
/* Declare functions used by various EXTRA_EM_FILEs. */
static void gld${EMULATION_NAME}_before_parse (void);
static void gld${EMULATION_NAME}_before_allocation (void);
static bfd_boolean gld${EMULATION_NAME}_place_orphan
(lang_input_statement_type *file, asection *s);
-static void gld${EMULATION_NAME}_finish (void);
+static void gld${EMULATION_NAME}_layout_sections_again (void);
+static void gld${EMULATION_NAME}_finish (void) ATTRIBUTE_UNUSED;
EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
case ${target} in
- *-*-linux-gnu*)
+ *-*-linux-* | *-*-k*bsd*-*)
cat >>e${EMULATION_NAME}.c <<EOF
+#ifdef HAVE_GLOB
#include <glob.h>
+#endif
EOF
;;
esac
if (!entry->add_needed)
class |= DYN_NO_ADD_NEEDED;
+ if (entry->just_syms_flag
+ && (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) != 0)
+ einfo (_("%P%F: --just-symbols may not be used on DSO: %B\n"),
+ entry->the_bfd);
+
if (!class
|| (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0)
return FALSE;
return;
if (s->the_bfd == NULL)
return;
+ if (s->as_needed
+ && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
+ return;
if (bfd_stat (s->the_bfd, &st) != 0)
{
return;
}
+ /* Some operating systems, e.g. Windows, do not provide a meaningful
+ st_ino; they always set it to zero. (Windows does provide a
+ meaningful st_dev.) Do not indicate a duplicate library in that
+ case. While there is no guarantee that a system that provides
+ meaningful inode numbers will never set st_ino to zero, this is
+ merely an optimization, so we do not need to worry about false
+ negatives. */
if (st.st_dev == global_stat.st_dev
- && st.st_ino == global_stat.st_ino)
+ && st.st_ino == global_stat.st_ino
+ && st.st_ino != 0)
{
global_found = TRUE;
return;
EOF
case ${target} in
- *-*-linux-gnu*)
+ *-*-linux-* | *-*-k*bsd*-*)
cat >>e${EMULATION_NAME}.c <<EOF
{
struct bfd_link_needed_list *l;
EOF
case ${target} in
- *-*-linux-gnu*)
+ *-*-linux-* | *-*-k*bsd*-*)
cat >>e${EMULATION_NAME}.c <<EOF
/* For a native linker, check the file /etc/ld.so.conf for directories
in which we may find shared libraries. /etc/ld.so.conf is really
const char *pattern)
{
char *newp = NULL;
+#ifdef HAVE_GLOB
glob_t gl;
+#endif
if (pattern[0] != '/')
{
pattern = newp;
}
+#ifdef HAVE_GLOB
if (glob (pattern, 0, NULL, &gl) == 0)
{
size_t i;
gld${EMULATION_NAME}_parse_ld_so_conf (info, gl.gl_pathv[i]);
globfree (&gl);
}
+#else
+ /* If we do not have glob, treat the pattern as a literal filename. */
+ gld${EMULATION_NAME}_parse_ld_so_conf (info, pattern);
+#endif
if (newp)
free (newp);
if (global_found)
return;
+ /* If this input file was an as-needed entry, and wasn't found to be
+ needed at the stage it was linked, then don't say we have loaded it. */
+ if (s->as_needed
+ && (s->the_bfd == NULL
+ || (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0))
+ return;
+
if (s->filename != NULL)
{
const char *f;
size_t len;
search_dirs_type *search;
EOF
-if [ "x${USE_LIBPATH}" = xyes ] ; then
+if [ "x${NATIVE}" = xyes ] ; then
cat >>e${EMULATION_NAME}.c <<EOF
const char *lib_path;
+EOF
+fi
+if [ "x${USE_LIBPATH}" = xyes ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
struct bfd_link_needed_list *rp;
int found;
EOF
EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
case ${target} in
- *-*-linux-gnu*)
+ *-*-linux-* | *-*-k*bsd*-*)
cat >>e${EMULATION_NAME}.c <<EOF
if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
break;
will do no harm. */
if (strcmp (exp->assign.dst, ".") != 0)
{
- if (!bfd_elf_record_link_assignment (output_bfd, &link_info,
- exp->assign.dst, provide))
+ if (!bfd_elf_record_link_assignment (&link_info, exp->assign.dst,
+ provide))
einfo ("%P%F: failed to record assignment to %s: %E\n",
exp->assign.dst);
}
ELF_INTERPRETER_SET_DEFAULT="
if (sinterp != NULL)
{
- sinterp->contents = ${ELF_INTERPRETER_NAME};
- sinterp->size = strlen (sinterp->contents) + 1;
+ sinterp->contents = (unsigned char *) ${ELF_INTERPRETER_NAME};
+ sinterp->size = strlen ((char *) sinterp->contents) + 1;
}
"
(const char * const *) command_line.auxiliary_filters,
&link_info, &sinterp, lang_elf_version_info)))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
${ELF_INTERPRETER_SET_DEFAULT}
/* Let the user override the dynamic linker we are using. */
if (command_line.interpreter != NULL
/* Clobber the section size, so that we don't waste copying the
warning into the output file. */
s->size = 0;
+
+ /* Also set SEC_EXCLUDE, so that symbols defined in the warning
+ section don't get copied to the output. */
+ s->flags |= SEC_EXCLUDE;
}
}
+
+ before_allocation_default ();
+
+ if (!bfd_elf_size_dynsym_hash_dynstr (output_bfd, &link_info))
+ einfo ("%P%F: failed to set dynamic section sizes: %E\n");
}
EOF
lang_output_section_statement_type *after;
lang_output_section_statement_type *os;
int isdyn = 0;
+ int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
+ unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
secname = bfd_get_section_name (s->owner, s);
if (! link_info.relocatable
&& link_info.combreloc
- && (s->flags & SEC_ALLOC)
- && strncmp (secname, ".rel", 4) == 0)
+ && (s->flags & SEC_ALLOC))
{
- if (secname[4] == 'a')
- secname = ".rela.dyn";
- else
- secname = ".rel.dyn";
- isdyn = 1;
+ if (iself)
+ switch (sh_type)
+ {
+ case SHT_RELA:
+ secname = ".rela.dyn";
+ isdyn = 1;
+ break;
+ case SHT_REL:
+ secname = ".rel.dyn";
+ isdyn = 1;
+ break;
+ default:
+ break;
+ }
+ else if (strncmp (secname, ".rel", 4) == 0)
+ {
+ secname = secname[4] == 'a' ? ".rela.dyn" : ".rel.dyn";
+ isdyn = 1;
+ }
}
if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s)))
if (os != NULL
&& (os->bfd_section == NULL
|| os->bfd_section->flags == 0
- || ((s->flags ^ os->bfd_section->flags)
- & (SEC_LOAD | SEC_ALLOC)) == 0))
+ || (bfd_match_sections_by_type (output_bfd,
+ os->bfd_section,
+ s->owner, s)
+ && ((s->flags ^ os->bfd_section->flags)
+ & (SEC_LOAD | SEC_ALLOC)) == 0)))
{
/* We already have an output section statement with this
name, and its bfd section, if any, has compatible flags.
if ((s->flags & SEC_ALLOC) == 0)
;
else if ((s->flags & SEC_LOAD) != 0
- && strncmp (secname, ".note", 5) == 0)
+ && ((iself && sh_type == SHT_NOTE)
+ || (!iself && strncmp (secname, ".note", 5) == 0)))
place = &hold[orphan_interp];
else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
place = &hold[orphan_bss];
place = &hold[orphan_sdata];
else if ((s->flags & SEC_READONLY) == 0)
place = &hold[orphan_data];
- else if (strncmp (secname, ".rel", 4) == 0
+ else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL))
+ || (!iself && strncmp (secname, ".rel", 4) == 0))
&& (s->flags & SEC_LOAD) != 0)
place = &hold[orphan_rel];
else if ((s->flags & SEC_CODE) == 0)
cat >>e${EMULATION_NAME}.c <<EOF
static void
-gld${EMULATION_NAME}_finish (void)
+gld${EMULATION_NAME}_layout_sections_again (void)
{
- if (bfd_elf_discard_info (output_bfd, &link_info))
- {
- lang_reset_memory_regions ();
+ lang_reset_memory_regions ();
- /* Resize the sections. */
- lang_size_sections (stat_ptr->head, abs_output_section,
- &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE);
+ /* Resize the sections. */
+ lang_size_sections (NULL, TRUE);
- /* Redo special stuff. */
- ldemul_after_allocation ();
+ /* Redo special stuff. */
+ ldemul_after_allocation ();
- /* Do the assignments again. */
- lang_do_assignments (stat_ptr->head, abs_output_section,
- (fill_type *) 0, (bfd_vma) 0);
- }
+ /* Do the assignments again. */
+ lang_do_assignments ();
+}
+
+static void
+gld${EMULATION_NAME}_finish (void)
+{
+ if (bfd_elf_discard_info (output_bfd, &link_info))
+ gld${EMULATION_NAME}_layout_sections_again ();
+
+ finish_default ();
}
EOF
fi