rm -f e${EMULATION_NAME}.c
(echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
fragment <<EOF
-/* Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2015 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
#include "bfdlink.h"
#include "getopt.h"
#include "libiberty.h"
+#include "filenames.h"
#include "ld.h"
#include "ldmain.h"
#include "ldexp.h"
#include "ldlex.h"
#include "ldmisc.h"
#include "ldctor.h"
+#include "ldbuildid.h"
#include "coff/internal.h"
/* FIXME: See bfd/peXXigen.c for why we include an architecture specific
#include "coff/i386.h"
#include "coff/pe.h"
-/* FIXME: This is a BFD internal header file, and we should not be
+/* FIXME: These are BFD internal header files, and we should not be
using it here. */
#include "../bfd/libcoff.h"
+#include "../bfd/libpei.h"
#include "deffile.h"
#include "pe-dll.h"
#if defined(TARGET_IS_i386pe) \
|| defined(TARGET_IS_shpe) \
- || defined(TARGET_IS_mipspe) \
|| defined(TARGET_IS_armpe) \
|| defined(TARGET_IS_arm_epoc_pe) \
|| defined(TARGET_IS_arm_wince_pe)
static char * thumb_entry_symbol = NULL;
static lang_assignment_statement_type *image_base_statement = 0;
static unsigned short pe_dll_characteristics = 0;
+static bfd_boolean insert_timestamp = TRUE;
+static const char *emit_build_id;
#ifdef DLL_SUPPORT
static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable. */
static char *pe_out_def_filename = NULL;
static char *pe_implib_filename = NULL;
static int pe_enable_auto_image_base = 0;
+static unsigned long pe_auto_image_base = 0x61500000;
static char *pe_dll_search_prefix = NULL;
#endif
ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
output_filename = "${EXECUTABLE_NAME:-a.exe}";
#ifdef DLL_SUPPORT
- config.dynamic_link = TRUE;
+ input_flags.dynamic = TRUE;
config.has_shared = 1;
EOF
# Cygwin no longer wants these noisy warnings. Other PE
# targets might like to consider adding themselves here.
+# See also the mail thread starting here for the reason why
+# merge_rdata defaults to 0 for cygwin:
+# http://cygwin.com/ml/cygwin-apps/2013-04/msg00187.html
case ${target} in
*-*-cygwin*)
default_auto_import=1
- default_merge_rdata=1
+ default_merge_rdata=0
;;
i[3-7]86-*-mingw* | x86_64-*-mingw*)
default_auto_import=1
(OPTION_EXCLUDE_LIBS + 1)
#define OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC \
(OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC + 1)
-#define OPTION_LARGE_ADDRESS_AWARE \
- (OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC + 1)
+#define OPTION_LARGE_ADDRESS_AWARE (OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC + 1)
+#define OPTION_DISABLE_LARGE_ADDRESS_AWARE \
+ (OPTION_LARGE_ADDRESS_AWARE + 1)
#define OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1 \
- (OPTION_LARGE_ADDRESS_AWARE + 1)
+ (OPTION_DISABLE_LARGE_ADDRESS_AWARE + 1)
#define OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2 \
(OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1 + 1)
#define OPTION_EXCLUDE_MODULES_FOR_IMPLIB \
(OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2 + 1)
#define OPTION_USE_NUL_PREFIXED_IMPORT_TABLES \
(OPTION_EXCLUDE_MODULES_FOR_IMPLIB + 1)
-#define OPTION_NO_LEADING_UNDERSCORE \
- (OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1)
-#define OPTION_LEADING_UNDERSCORE \
- (OPTION_NO_LEADING_UNDERSCORE + 1)
+#define OPTION_NO_LEADING_UNDERSCORE (OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1)
+#define OPTION_LEADING_UNDERSCORE (OPTION_NO_LEADING_UNDERSCORE + 1)
#define OPTION_ENABLE_LONG_SECTION_NAMES \
(OPTION_LEADING_UNDERSCORE + 1)
#define OPTION_DISABLE_LONG_SECTION_NAMES \
(OPTION_ENABLE_LONG_SECTION_NAMES + 1)
-/* DLLCharacteristics flags */
+/* DLLCharacteristics flags. */
#define OPTION_DYNAMIC_BASE (OPTION_DISABLE_LONG_SECTION_NAMES + 1)
#define OPTION_FORCE_INTEGRITY (OPTION_DYNAMIC_BASE + 1)
#define OPTION_NX_COMPAT (OPTION_FORCE_INTEGRITY + 1)
-#define OPTION_NO_ISOLATION (OPTION_NX_COMPAT + 1)
+#define OPTION_NO_ISOLATION (OPTION_NX_COMPAT + 1)
#define OPTION_NO_SEH (OPTION_NO_ISOLATION + 1)
#define OPTION_NO_BIND (OPTION_NO_SEH + 1)
#define OPTION_WDM_DRIVER (OPTION_NO_BIND + 1)
#define OPTION_TERMINAL_SERVER_AWARE (OPTION_WDM_DRIVER + 1)
+/* Determinism. */
+#define OPTION_INSERT_TIMESTAMP (OPTION_TERMINAL_SERVER_AWARE + 1)
+#define OPTION_NO_INSERT_TIMESTAMP (OPTION_INSERT_TIMESTAMP + 1)
+#define OPTION_BUILD_ID (OPTION_NO_INSERT_TIMESTAMP + 1)
static void
gld${EMULATION_NAME}_add_options
int nrl ATTRIBUTE_UNUSED,
struct option **really_longopts ATTRIBUTE_UNUSED)
{
- static const struct option xtra_long[] = {
- /* PE options */
+ static const struct option xtra_long[] =
+ {
+ /* PE options. */
{"base-file", required_argument, NULL, OPTION_BASE_FILE},
{"dll", no_argument, NULL, OPTION_DLL},
{"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
OPTION_USE_NUL_PREFIXED_IMPORT_TABLES},
{"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE},
{"leading-underscore", no_argument, NULL, OPTION_LEADING_UNDERSCORE},
+ {"insert-timestamp", no_argument, NULL, OPTION_INSERT_TIMESTAMP},
+ {"no-insert-timestamp", no_argument, NULL, OPTION_NO_INSERT_TIMESTAMP},
#ifdef DLL_SUPPORT
/* getopt allows abbreviations, so we do this to stop it
from treating -o as an abbreviation for this option. */
treating -c as an abbreviation for these --compat-implib. */
{"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT},
{"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT},
- {"enable-auto-image-base", no_argument, NULL, OPTION_ENABLE_AUTO_IMAGE_BASE},
+ {"enable-auto-image-base", optional_argument, NULL, OPTION_ENABLE_AUTO_IMAGE_BASE},
{"disable-auto-image-base", no_argument, NULL, OPTION_DISABLE_AUTO_IMAGE_BASE},
{"dll-search-prefix", required_argument, NULL, OPTION_DLL_SEARCH_PREFIX},
{"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
{"enable-runtime-pseudo-reloc-v2", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2},
#endif
{"large-address-aware", no_argument, NULL, OPTION_LARGE_ADDRESS_AWARE},
+ {"disable-large-address-aware", no_argument, NULL, OPTION_DISABLE_LARGE_ADDRESS_AWARE},
{"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
{"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
{"dynamicbase",no_argument, NULL, OPTION_DYNAMIC_BASE},
{"no-bind", no_argument, NULL, OPTION_NO_BIND},
{"wdmdriver", no_argument, NULL, OPTION_WDM_DRIVER},
{"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},
+ {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
{NULL, no_argument, NULL, 0}
};
#define U_SIZE(CSTR) \
(sizeof (CSTR) + (is_underscoring () == 0 ? 0 : 1))
-#define D(field,symbol,def,usc) {&pe.field,sizeof(pe.field), def, symbol, 0, usc}
+#define D(field,symbol,def,usc) {&pe.field, sizeof (pe.field), def, symbol, 0, usc}
static definfo init[] =
{
fprintf (file, _(" --support-old-code Support interworking with old code\n"));
fprintf (file, _(" --[no-]leading-underscore Set explicit symbol underscore prefix mode\n"));
fprintf (file, _(" --thumb-entry=<symbol> Set the entry point to be Thumb <symbol>\n"));
+ fprintf (file, _(" --[no-]insert-timestamp Use a real timestamp rather than zero (default).\n"));
+ fprintf (file, _(" This makes binaries non-deterministic\n"));
#ifdef DLL_SUPPORT
fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n"));
fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n"));
fprintf (file, _(" --kill-at Remove @nn from exported symbols\n"));
fprintf (file, _(" --out-implib <file> Generate import library\n"));
fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n"));
- fprintf (file, _(" --warn-duplicate-exports Warn about duplicate exports.\n"));
+ fprintf (file, _(" --warn-duplicate-exports Warn about duplicate exports\n"));
fprintf (file, _(" --compat-implib Create backward compatible import libs;\n\
create __imp_<SYMBOL> as well.\n"));
- fprintf (file, _(" --enable-auto-image-base Automatically choose image base for DLLs\n\
- unless user specifies one\n"));
+ fprintf (file, _(" --enable-auto-image-base[=<address>] Automatically choose image base for DLLs\n\
+ (optionally starting with address) unless\n\
+ specifically set with --image-base\n"));
fprintf (file, _(" --disable-auto-image-base Do not auto-choose image base. (default)\n"));
fprintf (file, _(" --dll-search-prefix=<string> When linking dynamically to a dll without\n\
an importlib, use <string><basename>.dll\n\
#endif
fprintf (file, _(" --large-address-aware Executable supports virtual addresses\n\
greater than 2 gigabytes\n"));
+ fprintf (file, _(" --disable-large-address-aware Executable does not support virtual\n\
+ addresses greater than 2 gigabytes\n"));
fprintf (file, _(" --enable-long-section-names Use long COFF section names even in\n\
executable image files\n"));
fprintf (file, _(" --disable-long-section-names Never use long COFF section names, even\n\
fprintf (file, _(" --no-bind Do not bind this image\n"));
fprintf (file, _(" --wdmdriver Driver uses the WDM model\n"));
fprintf (file, _(" --tsaware Image is Terminal Server aware\n"));
+ fprintf (file, _(" --build-id[=STYLE] Generate build ID\n"));
}
einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg);
}
+#define DEFAULT_BUILD_ID_STYLE "md5"
static bfd_boolean
gld${EMULATION_NAME}_handle_option (int optc)
case OPTION_BASE_FILE:
link_info.base_file = fopen (optarg, FOPEN_WB);
if (link_info.base_file == NULL)
- {
- /* xgettext:c-format */
- fprintf (stderr, _("%s: Can't open base file %s\n"),
- program_name, optarg);
- xexit (1);
- }
+ einfo (_("%F%P: cannot open base file %s\n"), optarg);
break;
/* PE options. */
case OPTION_LEADING_UNDERSCORE:
pe_leading_underscore = 1;
break;
+ case OPTION_INSERT_TIMESTAMP:
+ insert_timestamp = TRUE;
+ break;
+ case OPTION_NO_INSERT_TIMESTAMP:
+ insert_timestamp = FALSE;
+ break;
#ifdef DLL_SUPPORT
case OPTION_OUT_DEF:
pe_out_def_filename = xstrdup (optarg);
break;
case OPTION_ENABLE_AUTO_IMAGE_BASE:
pe_enable_auto_image_base = 1;
+ if (optarg && *optarg)
+ {
+ char *end;
+ pe_auto_image_base = strtoul (optarg, &end, 0);
+ /* XXX should check that we actually parsed something */
+ }
break;
case OPTION_DISABLE_AUTO_IMAGE_BASE:
pe_enable_auto_image_base = 0;
case OPTION_LARGE_ADDRESS_AWARE:
real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
break;
+ case OPTION_DISABLE_LARGE_ADDRESS_AWARE:
+ real_flags &= ~ IMAGE_FILE_LARGE_ADDRESS_AWARE;
+ break;
case OPTION_ENABLE_LONG_SECTION_NAMES:
pe_use_coff_long_section_names = 1;
break;
case OPTION_TERMINAL_SERVER_AWARE:
pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
break;
+ case OPTION_BUILD_ID:
+ if (emit_build_id != NULL)
+ {
+ free ((char *) emit_build_id);
+ emit_build_id = NULL;
+ }
+ if (optarg == NULL)
+ optarg = DEFAULT_BUILD_ID_STYLE;
+ if (strcmp (optarg, "none"))
+ emit_build_id = xstrdup (optarg);
+ break;
}
/* Set DLLCharacteristics bits */
compute_dll_image_base (const char *ofile)
{
unsigned long hash = strhash (ofile);
- return 0x61300000 + ((hash << 16) & 0x0FFC0000);
+ return pe_auto_image_base + ((hash << 16) & 0x0FFC0000);
}
#endif
lang_assignment_statement_type *rv;
rv = lang_add_assignment (exp_assign (GET_INIT_SYMBOL_NAME (j),
- exp_intop (val)));
+ exp_intop (val), FALSE));
if (init[j].size == sizeof (short))
*(short *) init[j].ptr = val;
else if (init[j].size == sizeof (int))
static bfd_boolean
pr_sym (struct bfd_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
{
- if (pe_dll_extra_pe_debug)
- printf ("+%s\n", h->string);
+ printf ("+%s\n", h->string);
return TRUE;
}
#endif /* DLL_SUPPORT */
-static void
+static void
debug_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
{
int *found = (int *) obj;
*found = 1;
}
+static bfd_boolean
+pecoff_checksum_contents (bfd *abfd,
+ void (*process) (const void *, size_t, void *),
+ void *arg)
+{
+ file_ptr filepos = (file_ptr) 0;
+
+ while (1)
+ {
+ unsigned char b;
+ int status;
+
+ if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ return 0;
+
+ status = bfd_bread (&b, (bfd_size_type) 1, abfd);
+ if (status < 1)
+ {
+ break;
+ }
+
+ (*process) (&b, 1, arg);
+ filepos += 1;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+write_build_id (bfd *abfd)
+{
+ struct pe_tdata *t = pe_data (abfd);
+ asection *asec;
+ struct bfd_link_order *link_order = NULL;
+ unsigned char *contents;
+ bfd_size_type size;
+ bfd_size_type build_id_size;
+ unsigned char *build_id;
+
+ /* Find the section the .buildid output section has been merged info. */
+ for (asec = abfd->sections; asec != NULL; asec = asec->next)
+ {
+ struct bfd_link_order *l = NULL;
+ for (l = asec->map_head.link_order; l != NULL; l = l->next)
+ {
+ if ((l->type == bfd_indirect_link_order))
+ {
+ if (l->u.indirect.section == t->build_id.sec)
+ {
+ link_order = l;
+ break;
+ }
+ }
+ }
+
+ if (link_order)
+ break;
+ }
+
+ if (!link_order)
+ {
+ einfo (_("%P: warning: .buildid section discarded,"
+ " --build-id ignored.\n"));
+ return TRUE;
+ }
+
+ if (t->build_id.sec->contents == NULL)
+ t->build_id.sec->contents = (unsigned char *) xmalloc (t->build_id.sec->size);
+ contents = t->build_id.sec->contents;
+ size = t->build_id.sec->size;
+
+ build_id_size = compute_build_id_size (t->build_id.style);
+ build_id = xmalloc (build_id_size);
+ generate_build_id (abfd, t->build_id.style, pecoff_checksum_contents, build_id, build_id_size);
+
+ bfd_vma ib = pe_data (link_info.output_bfd)->pe_opthdr.ImageBase;
+
+ /* Construct a debug directory entry which points to an immediately following CodeView record. */
+ struct internal_IMAGE_DEBUG_DIRECTORY idd;
+ idd.Characteristics = 0;
+ idd.TimeDateStamp = 0;
+ idd.MajorVersion = 0;
+ idd.MinorVersion = 0;
+ idd.Type = PE_IMAGE_DEBUG_TYPE_CODEVIEW;
+ idd.SizeOfData = sizeof (CV_INFO_PDB70) + 1;
+ idd.AddressOfRawData = asec->vma - ib + link_order->offset
+ + sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
+ idd.PointerToRawData = asec->filepos + link_order->offset
+ + sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
+
+ struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *)contents;
+ _bfd_XXi_swap_debugdir_out (abfd, &idd, ext);
+
+ /* Write the debug directory entry. */
+ if (bfd_seek (abfd, asec->filepos + link_order->offset, SEEK_SET) != 0)
+ return 0;
+
+ if ((bfd_bwrite (contents, size, abfd) != size))
+ return 0;
+
+ /* Construct the CodeView record. */
+ CODEVIEW_INFO cvinfo;
+ cvinfo.CVSignature = CVINFO_PDB70_CVSIGNATURE;
+ cvinfo.Age = 1;
+
+ /* Zero pad or truncate the generated build_id to fit in the CodeView record. */
+ memset (&(cvinfo.Signature), 0, CV_INFO_SIGNATURE_LENGTH);
+ memcpy (&(cvinfo.Signature), build_id, (build_id_size > CV_INFO_SIGNATURE_LENGTH)
+ ? CV_INFO_SIGNATURE_LENGTH : build_id_size);
+
+ free (build_id);
+
+ /* Write the codeview record. */
+ if (_bfd_XXi_write_codeview_record (abfd, idd.PointerToRawData, &cvinfo) == 0)
+ return 0;
+
+ /* Record the location of the debug directory in the data directory. */
+ pe_data (link_info.output_bfd)->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
+ = asec->vma - ib + link_order->offset;
+ pe_data (link_info.output_bfd)->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
+ = sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
+
+ return TRUE;
+}
+
+/* Make .buildid section, and set up coff_tdata->build_id. */
+static bfd_boolean
+setup_build_id (bfd *ibfd)
+{
+ asection *s;
+ flagword flags;
+
+ if (!validate_build_id_style (emit_build_id))
+ {
+ einfo ("%P: warning: unrecognized --build-id style ignored.\n");
+ return FALSE;
+ }
+
+ flags = (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY | SEC_DATA);
+ s = bfd_make_section_anyway_with_flags (ibfd, ".buildid", flags);
+ if (s != NULL)
+ {
+ struct pe_tdata *t = pe_data (link_info.output_bfd);
+ t->build_id.after_write_object_contents = &write_build_id;
+ t->build_id.style = emit_build_id;
+ t->build_id.sec = s;
+
+ /* Section is a fixed size:
+ One IMAGE_DEBUG_DIRECTORY entry, of type IMAGE_DEBUG_TYPE_CODEVIEW,
+ pointing at a CV_INFO_PDB70 record containing the build-id, with a
+ null byte for PdbFileName. */
+ s->size = sizeof (struct external_IMAGE_DEBUG_DIRECTORY)
+ + sizeof (CV_INFO_PDB70) + 1;
+
+ return TRUE;
+ }
+
+ einfo ("%P: warning: Cannot create .buildid section,"
+ " --build-id ignored.\n");
+ return FALSE;
+}
+
static void
gld_${EMULATION_NAME}_after_open (void)
{
printf ("-%s\n", sym->root.string);
bfd_hash_traverse (&link_info.hash->table, pr_sym, NULL);
- for (a = link_info.input_bfds; a; a = a->link_next)
+ for (a = link_info.input_bfds; a; a = a->link.next)
printf ("*%s\n",a->filename);
}
#endif
+ if (emit_build_id != NULL)
+ {
+ bfd *abfd;
+
+ /* Find a COFF input. */
+ for (abfd = link_info.input_bfds;
+ abfd != (bfd *) NULL; abfd = abfd->link.next)
+ if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
+ break;
+
+ /* If there are no COFF input files do not try to
+ add a build-id section. */
+ if (abfd == NULL
+ || !setup_build_id (abfd))
+ {
+ free ((char *) emit_build_id);
+ emit_build_id = NULL;
+ }
+ }
+
/* Pass the wacky PE command line options into the output bfd.
FIXME: This should be done via a function, rather than by
including an internal BFD header. */
pe_data (link_info.output_bfd)->pe_opthdr = pe;
pe_data (link_info.output_bfd)->dll = init[DLLOFF].value;
pe_data (link_info.output_bfd)->real_flags |= real_flags;
+ pe_data (link_info.output_bfd)->insert_timestamp = insert_timestamp;
/* At this point we must decide whether to use long section names
in the output or not. If the user hasn't explicitly specified
find it, so enable it in that case. */
if (pe_use_coff_long_section_names < 0 && link_info.strip == strip_none)
{
- /* Iterate over all sections of all input BFDs, checking
- for any that begin 'debug_' and are long names. */
- LANG_FOR_EACH_INPUT_STATEMENT (is)
+ if (link_info.relocatable)
+ pe_use_coff_long_section_names = 1;
+ else
{
- int found_debug = 0;
- bfd_map_over_sections (is->the_bfd, debug_section_p, &found_debug);
- if (found_debug)
- {
- pe_use_coff_long_section_names = 1;
- break;
- }
+ /* Iterate over all sections of all input BFDs, checking
+ for any that begin 'debug_' and are long names. */
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ int found_debug = 0;
+
+ bfd_map_over_sections (is->the_bfd, debug_section_p, &found_debug);
+ if (found_debug)
+ {
+ pe_use_coff_long_section_names = 1;
+ break;
+ }
+ }
}
}
? bfd_get_filename (blhe->u.def.section->owner->my_archive)
: bfd_get_filename (blhe->u.def.section->owner);
- if (strcmp (bfd_get_filename (is->the_bfd->my_archive),
- other_bfd_filename) == 0)
+ if (filename_cmp (bfd_get_filename
+ (is->the_bfd->my_archive),
+ other_bfd_filename) == 0)
continue;
/* Rename this implib to match the other one. */
extension, and use that for the remainder of the
comparisons. */
pnt = strrchr (is3->the_bfd->filename, '.');
- if (pnt != NULL && strcmp (pnt, ".dll") == 0)
+ if (pnt != NULL && filename_cmp (pnt, ".dll") == 0)
break;
}
/* Skip static members, ie anything with a .obj
extension. */
pnt = strrchr (is2->the_bfd->filename, '.');
- if (pnt != NULL && strcmp (pnt, ".obj") == 0)
+ if (pnt != NULL && filename_cmp (pnt, ".obj") == 0)
continue;
- if (strcmp (is3->the_bfd->filename,
- is2->the_bfd->filename))
+ if (filename_cmp (is3->the_bfd->filename,
+ is2->the_bfd->filename))
{
is_ms_arch = 0;
break;
then leave the filename alone. */
pnt = strrchr (is->the_bfd->filename, '.');
- if (is_ms_arch && (strcmp (pnt, ".dll") == 0))
+ if (is_ms_arch && (filename_cmp (pnt, ".dll") == 0))
{
int idata2 = 0, reloc_count=0;
asection *sec;
/* If the symbol in the stub section has no other
undefined references, exclude the stub section
from the final link. */
- if (blhe && (blhe->type == bfd_link_hash_defined)
- && (blhe->u.undef.next == NULL))
+ if (blhe != NULL
+ && blhe->type == bfd_link_hash_defined
+ && blhe->u.undef.next == NULL
+ && blhe != link_info.hash->undefs_tail)
stub_sec->flags |= SEC_EXCLUDE;
}
}
#ifdef DLL_SUPPORT
const char *ext = entry->filename + strlen (entry->filename) - 4;
- if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0)
+ if (filename_cmp (ext, ".def") == 0 || filename_cmp (ext, ".DEF") == 0)
{
pe_def_file = def_file_parse (entry->filename, pe_def_file);
= pe_def_file->base_address;
init[IMAGEBASEOFF].inited = 1;
if (image_base_statement)
- image_base_statement->exp = exp_assign ("__image_base__",
- exp_intop (pe.ImageBase));
+ image_base_statement->exp
+ = exp_assign ("__image_base__", exp_intop (pe.ImageBase),
+ FALSE);
}
if (pe_def_file->stack_reserve != -1
#ifdef TARGET_IS_shpe
pe_dll_id_target ("pei-shl");
#endif
-#ifdef TARGET_IS_mipspe
- pe_dll_id_target ("pei-mips");
-#endif
#ifdef TARGET_IS_armpe
pe_dll_id_target ("pei-arm-little");
#endif
#ifdef DLL_SUPPORT
if (link_info.shared
-#if !defined(TARGET_IS_shpe) && !defined(TARGET_IS_mipspe)
+#if !defined(TARGET_IS_shpe)
|| (!link_info.relocatable && pe_def_file->num_exports != 0)
#endif
)
if (pe_implib_filename)
pe_dll_generate_implib (pe_def_file, pe_implib_filename, &link_info);
}
-#if defined(TARGET_IS_shpe) || defined(TARGET_IS_mipspe)
+#if defined(TARGET_IS_shpe)
/* ARM doesn't need relocs. */
else
{
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. */
- lang_add_section (&add_child, s, os);
+ lang_add_section (&add_child, s, NULL, os);
break;
}
unused one and use that. */
if (os == NULL && match_by_name)
{
- lang_add_section (&match_by_name->children, s, match_by_name);
+ lang_add_section (&match_by_name->children, s, NULL, match_by_name);
return match_by_name;
}
->output_section_statement);
}
- /* All sections in an executable must be aligned to a page boundary. */
+ /* All sections in an executable must be aligned to a page boundary.
+ In a relocatable link, just preserve the incoming alignment; the
+ address is discarded by lang_insert_orphan in that case, anyway. */
address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
os = lang_insert_orphan (s, secname, constraint, after, place, address,
&add_child);
+ if (link_info.relocatable)
+ {
+ os->section_alignment = s->alignment_power;
+ os->bfd_section->alignment_power = s->alignment_power;
+ }
}
/* If the section name has a '\$', sort it with the other '\$'
unsigned int i;
- if (! entry->maybe_archive)
+ if (! entry->flags.maybe_archive || entry->flags.full_name_provided)
return FALSE;
filename = entry->filename;
gld_${EMULATION_NAME}_list_options,
gld_${EMULATION_NAME}_recognized_file,
gld_${EMULATION_NAME}_find_potential_libraries,
- NULL /* new_vers_pattern. */
+ NULL, /* new_vers_pattern. */
+ NULL /* extra_map_file_text. */
};
EOF