rm -f e${EMULATION_NAME}.c
(echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
fragment <<EOF
-/* Copyright (C) 1995-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
#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;
#define OPTION_STDCALL_ALIASES (OPTION_KILL_ATS + 1)
#define OPTION_ENABLE_STDCALL_FIXUP (OPTION_STDCALL_ALIASES + 1)
#define OPTION_DISABLE_STDCALL_FIXUP (OPTION_ENABLE_STDCALL_FIXUP + 1)
-#define OPTION_IMPLIB_FILENAME (OPTION_DISABLE_STDCALL_FIXUP + 1)
-#define OPTION_THUMB_ENTRY (OPTION_IMPLIB_FILENAME + 1)
+#define OPTION_THUMB_ENTRY (OPTION_DISABLE_STDCALL_FIXUP + 1)
#define OPTION_WARN_DUPLICATE_EXPORTS (OPTION_THUMB_ENTRY + 1)
#define OPTION_IMP_COMPAT (OPTION_WARN_DUPLICATE_EXPORTS + 1)
#define OPTION_ENABLE_AUTO_IMAGE_BASE (OPTION_IMP_COMPAT + 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)
+ (OPTION_LARGE_ADDRESS_AWARE + 1)
#define OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1 \
(OPTION_DISABLE_LARGE_ADDRESS_AWARE + 1)
#define OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2 \
(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 \
{"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES},
{"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP},
{"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP},
- {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME},
{"warn-duplicate-exports", no_argument, NULL, OPTION_WARN_DUPLICATE_EXPORTS},
/* getopt() allows abbreviations, so we do this to stop it from
treating -c as an abbreviation for these --compat-implib. */
underscore. */
#define GET_INIT_SYMBOL_NAME(IDX) \
(init[(IDX)].symbol \
- + ((init[(IDX)].is_c_symbol == FALSE || (is_underscoring () != 0)) ? 0 : 1))
+ + ((!init[(IDX)].is_c_symbol || is_underscoring () != 0) ? 0 : 1))
/* Decorates the C visible symbol by underscore, if target requires. */
#define U(CSTR) \
fprintf (file, _(" export, place into import library instead.\n"));
fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\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, _(" --compat-implib Create backward compatible import libs;\n\
executable image files\n"));
fprintf (file, _(" --disable-long-section-names Never use long COFF section names, even\n\
in object files\n"));
- fprintf (file, _(" --dynamicbase Image base address may be relocated using\n\
- address space layout randomization (ASLR)\n"));
- fprintf (file, _(" --forceinteg Code integrity checks are enforced\n"));
- fprintf (file, _(" --nxcompat Image is compatible with data execution prevention\n"));
- fprintf (file, _(" --no-isolation Image understands isolation but do not isolate the image\n"));
- fprintf (file, _(" --no-seh Image does not use SEH. No SE handler may\n\
- be called in this image\n"));
- fprintf (file, _(" --no-bind Do not bind this image\n"));
- fprintf (file, _(" --wdmdriver Driver uses the WDM model\n"));
+ fprintf (file, _(" --dynamicbase Image base address may be relocated using\n\
+ address space layout randomization (ASLR)\n"));
+ fprintf (file, _(" --forceinteg Code integrity checks are enforced\n"));
+ fprintf (file, _(" --nxcompat Image is compatible with data execution prevention\n"));
+ fprintf (file, _(" --no-isolation Image understands isolation but do not isolate the image\n"));
+ fprintf (file, _(" --no-seh Image does not use SEH. No SE handler may\n\
+ be called in this image\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"));
}
int i;
static const struct
- {
- const int value;
- const char *entry;
- }
+ {
+ const int value;
+ const char *entry;
+ }
v[] =
{
{ 1, "NtProcessStartup" },
}
else
{
-
for (i = 0; v[i].entry; i++)
- if (v[i].value == pe_subsystem)
- break;
+ if (v[i].value == pe_subsystem)
+ break;
/* If no match, use the default. */
if (v[i].entry != NULL)
- entry = v[i].entry;
+ entry = v[i].entry;
else
- entry = default_entry;
+ entry = default_entry;
}
initial_symbol_char = (is_underscoring () != 0 ? "_" : "");
if (v[i].name == NULL)
{
- einfo (_("%P%F: invalid subsystem type %s\n"), optarg);
+ einfo (_("%F%P: invalid subsystem type %s\n"), optarg);
return;
}
set_pe_name (name, strtoul (optarg, &end, 0));
if (end == optarg)
- einfo (_("%P%F: invalid hex number for PE parameter '%s'\n"), optarg);
+ einfo (_("%F%P: invalid hex number for PE parameter '%s'\n"), optarg);
optarg = end;
}
set_pe_value (comname);
}
else if (*optarg)
- einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg);
+ einfo (_("%F%P: strange hex info for PE parameter '%s'\n"), optarg);
}
#define DEFAULT_BUILD_ID_STYLE "md5"
case OPTION_DISABLE_STDCALL_FIXUP:
pe_enable_stdcall_fixup = 0;
break;
- case OPTION_IMPLIB_FILENAME:
- pe_implib_filename = xstrdup (optarg);
- break;
case OPTION_WARN_DUPLICATE_EXPORTS:
pe_dll_warn_dup_exports = 1;
break;
if (pe.FileAlignment > pe.SectionAlignment)
{
- einfo (_("%P: warning, file alignment > section alignment.\n"));
+ einfo (_("%P: warning, file alignment > section alignment\n"));
}
}
return TRUE;
}
+/* Change UNDEF to a defined symbol, taking data from SYM. */
+
+static void
+change_undef (struct bfd_link_hash_entry * undef,
+ struct bfd_link_hash_entry * sym)
+{
+ static bfd_boolean gave_warning_message = FALSE;
+
+ undef->type = bfd_link_hash_defined;
+ undef->u.def.value = sym->u.def.value;
+ undef->u.def.section = sym->u.def.section;
+
+ if (pe_enable_stdcall_fixup == -1)
+ {
+ einfo (_("%P: warning: resolving %s by linking to %s\n"),
+ undef->root.string, sym->root.string);
+
+ if (! gave_warning_message)
+ {
+ einfo (_("Use --enable-stdcall-fixup to disable these warnings\n"));
+ einfo (_("Use --disable-stdcall-fixup to disable these fixups\n"));
+ gave_warning_message = TRUE;
+ }
+ }
+
+ /* PR 19803: Make sure that the linked symbol is not garbage collected. */
+ lang_add_gc_name (sym->root.string);
+}
+
static void
pe_fixup_stdcalls (void)
{
- static int gave_warning_message = 0;
struct bfd_link_hash_entry *undef, *sym;
if (pe_dll_extra_pe_debug)
for (undef = link_info.hash->undefs; undef; undef=undef->u.undef.next)
if (undef->type == bfd_link_hash_undefined)
{
- char* at = strchr (undef->root.string, '@');
- int lead_at = (*undef->root.string == '@');
+ const char * name = undef->root.string;
+ char * at;
+ int lead_at = (*name == '@');
+
if (lead_at)
- at = strchr (undef->root.string + 1, '@');
+ at = strchr (name + 1, '@');
+ else
+ at = strchr (name, '@');
if (at || lead_at)
{
/* The symbol is a stdcall symbol, so let's look for a
cdecl symbol with the same name and resolve to that. */
- char *cname = xstrdup (undef->root.string);
+ char *cname = xstrdup (name);
if (lead_at)
*cname = '_';
- at = strchr (cname, '@');
if (at)
- *at = 0;
- sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1);
+ * strchr (cname, '@') = 0;
+ sym = bfd_link_hash_lookup (link_info.hash, cname, FALSE, FALSE, TRUE);
if (sym && sym->type == bfd_link_hash_defined)
- {
- undef->type = bfd_link_hash_defined;
- undef->u.def.value = sym->u.def.value;
- undef->u.def.section = sym->u.def.section;
-
- if (pe_enable_stdcall_fixup == -1)
- {
- einfo (_("Warning: resolving %s by linking to %s\n"),
- undef->root.string, cname);
- if (! gave_warning_message)
- {
- gave_warning_message = 1;
- einfo (_("Use --enable-stdcall-fixup to disable these warnings\n"));
- einfo (_("Use --disable-stdcall-fixup to disable these fixups\n"));
- }
- }
- }
+ change_undef (undef, sym);
}
else
{
/* The symbol is a cdecl symbol, so we look for stdcall
symbols - which means scanning the whole symbol table. */
- pe_undef_found_sym = 0;
+ pe_undef_found_sym = NULL;
bfd_link_hash_traverse (link_info.hash, pe_undef_cdecl_match,
- (char *) undef->root.string);
- sym = pe_undef_found_sym;
- if (sym)
- {
- undef->type = bfd_link_hash_defined;
- undef->u.def.value = sym->u.def.value;
- undef->u.def.section = sym->u.def.section;
-
- if (pe_enable_stdcall_fixup == -1)
- {
- einfo (_("Warning: resolving %s by linking to %s\n"),
- undef->root.string, sym->root.string);
- if (! gave_warning_message)
- {
- gave_warning_message = 1;
- einfo (_("Use --enable-stdcall-fixup to disable these warnings\n"));
- einfo (_("Use --disable-stdcall-fixup to disable these fixups\n"));
- }
- }
- }
+ (char *) name);
+ if (pe_undef_found_sym)
+ change_undef (undef, pe_undef_found_sym);
}
}
}
static int
-make_import_fixup (arelent *rel, asection *s)
+make_import_fixup (arelent *rel, asection *s, char *name)
{
struct bfd_symbol *sym = *rel->sym_ptr_ptr;
char addend[4];
(unsigned long) rel->address, (long) rel->addend);
if (! bfd_get_section_contents (s->owner, s, addend, rel->address, sizeof (addend)))
- einfo (_("%C: Cannot get section contents - auto-import exception\n"),
+ einfo (_("%P: %C: cannot get section contents - auto-import exception\n"),
s->owner, s, rel->address);
- pe_create_import_fixup (rel, s, bfd_get_32 (s->owner, addend));
+ pe_create_import_fixup (rel, s, bfd_get_32 (s->owner, addend), name);
return 1;
}
pe_find_data_imports (void)
{
struct bfd_link_hash_entry *undef, *sym;
+ size_t namelen;
+ char *buf, *name;
if (link_info.pei386_auto_import == 0)
return;
- for (undef = link_info.hash->undefs; undef; undef=undef->u.undef.next)
+ namelen = 0;
+ for (undef = link_info.hash->undefs; undef; undef = undef->u.undef.next)
+ {
+ if (undef->type == bfd_link_hash_undefined)
+ {
+ size_t len = strlen (undef->root.string);
+ if (namelen < len)
+ namelen = len;
+ }
+ }
+ if (namelen == 0)
+ return;
+
+ /* We are being a bit cunning here. The buffer will have space for
+ prefixes at the beginning. The prefix is modified here and in a
+ number of functions called from this function. */
+#define PREFIX_LEN 32
+ buf = xmalloc (PREFIX_LEN + namelen + 1);
+ name = buf + PREFIX_LEN;
+
+ for (undef = link_info.hash->undefs; undef; undef = undef->u.undef.next)
{
if (undef->type == bfd_link_hash_undefined)
{
- /* C++ symbols are *long*. */
-#define BUF_SIZE 4096
- char buf[BUF_SIZE];
+ char *impname;
if (pe_dll_extra_pe_debug)
printf ("%s:%s\n", __FUNCTION__, undef->root.string);
- if (strlen (undef->root.string) > (BUF_SIZE - 6))
- {
- /* PR linker/18466. */
- einfo (_("%P: internal error: symbol too long: %s\n"),
- undef->root.string);
- return;
- }
-
- sprintf (buf, "__imp_%s", undef->root.string);
+ strcpy (name, undef->root.string);
+ impname = name - (sizeof "__imp_" - 1);
+ memcpy (impname, "__imp_", sizeof "__imp_" - 1);
- sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
+ sym = bfd_link_hash_lookup (link_info.hash, impname, 0, 0, 1);
if (sym && sym->type == bfd_link_hash_defined)
{
{
static bfd_boolean warned = FALSE;
- info_msg (_("Info: resolving %s by linking to %s (auto-import)\n"),
- undef->root.string, buf);
+ info_msg (_("Info: resolving %s by linking to %s "
+ "(auto-import)\n"), name, impname);
/* PR linker/4844. */
if (! warned)
{
warned = TRUE;
- einfo (_("%P: warning: auto-importing has been activated without --enable-auto-import specified on the command line.\n\
-This should work unless it involves constant data structures referencing symbols from auto-imported DLLs.\n"));
+ einfo (_("%P: warning: auto-importing has been activated "
+ "without --enable-auto-import specified on the "
+ "command line; this should work unless it "
+ "involves constant data structures referencing "
+ "symbols from auto-imported DLLs\n"));
}
}
if (!bfd_generic_link_read_symbols (b))
{
- einfo (_("%B%F: could not read symbols: %E\n"), b);
+ einfo (_("%F%P: %pB: could not read symbols: %E\n"), b);
return;
}
for (i = 0; i < nsyms; i++)
{
- if (! CONST_STRNEQ (symbols[i]->name,
- U ("_head_")))
+ if (! CONST_STRNEQ (symbols[i]->name, U ("_head_")))
continue;
if (pe_dll_extra_pe_debug)
break;
}
- pe_walk_relocs_of_symbol (&link_info, undef->root.string,
- make_import_fixup);
+ pe_walk_relocs_of_symbol (&link_info, name, make_import_fixup);
/* Let's differentiate it somehow from defined. */
undef->type = bfd_link_hash_defweak;
/* We replace original name with __imp_ prefixed, this
1) may trash memory 2) leads to duplicate symbol generation.
- Still, IMHO it's better than having name poluted. */
+ Still, IMHO it's better than having name polluted. */
undef->root.string = sym->root.string;
undef->u.def.value = sym->u.def.value;
undef->u.def.section = sym->u.def.section;
}
}
}
+ free (buf);
}
static bfd_boolean
status = bfd_bread (&b, (bfd_size_type) 1, abfd);
if (status < 1)
- {
- break;
- }
+ {
+ break;
+ }
(*process) (&b, 1, arg);
filepos += 1;
{
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 (l->type == bfd_indirect_link_order)
+ {
+ if (l->u.indirect.section == t->build_id.sec)
+ {
+ link_order = l;
+ break;
+ }
+ }
+ }
if (link_order)
- break;
+ break;
}
if (!link_order)
{
einfo (_("%P: warning: .buildid section discarded,"
- " --build-id ignored.\n"));
+ " --build-id ignored\n"));
return TRUE;
}
if (!validate_build_id_style (emit_build_id))
{
- einfo ("%P: warning: unrecognized --build-id style ignored.\n");
+ einfo (_("%P: warning: unrecognized --build-id style ignored\n"));
return FALSE;
}
return TRUE;
}
- einfo ("%P: warning: Cannot create .buildid section,"
- " --build-id ignored.\n");
+ einfo (_("%P: warning: cannot create .buildid section,"
+ " --build-id ignored\n"));
return FALSE;
}
if (coff_data (link_info.output_bfd) == NULL
|| coff_data (link_info.output_bfd)->pe == 0)
- einfo (_("%F%P: cannot perform PE operations on non PE output file '%B'.\n"),
+ einfo (_("%F%P: cannot perform PE operations on non PE output file '%pB'\n"),
link_info.output_bfd);
pe_data (link_info.output_bfd)->pe_opthdr = pe;
These will only be created if the output format is an arm format,
hence we do not support linking and changing output formats at the
same time. Use a link followed by objcopy to change output formats. */
- einfo ("%F%X%P: error: cannot change output format whilst linking ARM binaries\n");
+ einfo (_("%F%P: error: cannot change output format "
+ "whilst linking %s binaries\n"), "ARM");
return;
}
{
if (!bfd_generic_link_read_symbols (is->the_bfd))
{
- einfo (_("%B%F: could not read symbols: %E\n"),
+ einfo (_("%F%P: %pB: could not read symbols: %E\n"),
is->the_bfd);
return;
}
if (nrelocs < 0)
{
free (relocs);
- einfo ("%X%P: unable to process relocs: %E\n");
+ einfo (_("%X%P: unable to process relocs: %E\n"));
return;
}
if (!bfd_generic_link_read_symbols (is->the_bfd))
{
- einfo (_("%B%F: could not read symbols: %E\n"),
+ einfo (_("%F%P: %pB: could not read symbols: %E\n"),
is->the_bfd);
return;
}
if (!ppc_process_before_allocation (is->the_bfd, &link_info))
{
/* xgettext:c-format */
- einfo (_("Errors encountered processing file %s\n"), is->filename);
+ einfo (_("%P: errors encountered processing file %s\n"), is->filename);
}
}
}
(is->the_bfd, & link_info, support_old_code))
{
/* xgettext:c-format */
- einfo (_("Errors encountered processing file %s for interworking\n"),
+ einfo (_("%P: errors encountered processing file %s for interworking\n"),
is->filename);
}
}
struct bfd_link_hash_entry *h;
sprintf (buf, "%s%s", U (""),
- pe_def_file->exports[i].internal_name);
+ pe_def_file->exports[i].internal_name);
h = bfd_link_hash_lookup (link_info.hash, buf, TRUE, TRUE, TRUE);
if (h == (struct bfd_link_hash_entry *) NULL)
- einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
+ einfo (_("%F%P: bfd_link_hash_lookup failed: %E\n"));
if (h->type == bfd_link_hash_new)
{
h->type = bfd_link_hash_undefined;
)
{
pe_dll_fill_sections (link_info.output_bfd, &link_info);
- if (pe_implib_filename)
- pe_dll_generate_implib (pe_def_file, pe_implib_filename, &link_info);
+ if (command_line.out_implib_filename)
+ pe_dll_generate_implib (pe_def_file, command_line.out_implib_filename,
+ &link_info);
}
#if defined(TARGET_IS_shpe)
/* ARM doesn't need relocs. */
orphan_init_done = 1;
}
+ flags = s->flags;
+ if (!bfd_link_relocatable (&link_info))
+ {
+ nexts = s;
+ while ((nexts = bfd_get_next_section_by_name (nexts->owner,
+ nexts)))
+ if (nexts->output_section == NULL
+ && (nexts->flags & SEC_EXCLUDE) == 0
+ && ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
+ && (nexts->owner->flags & DYNAMIC) == 0
+ && nexts->owner->usrdata != NULL
+ && !(((lang_input_statement_type *) nexts->owner->usrdata)
+ ->flags.just_syms))
+ flags = (((flags ^ SEC_READONLY)
+ | (nexts->flags ^ SEC_READONLY))
+ ^ SEC_READONLY);
+ }
+
/* Try to put the new output section in a reasonable place based
on the section name and section flags. */
- flags = s->flags;
- nexts = s;
- while ((nexts = bfd_get_next_section_by_name (nexts->owner, nexts)))
- if (nexts->output_section == NULL
- && (nexts->flags & SEC_EXCLUDE) == 0
- && ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
- && (nexts->owner->flags & DYNAMIC) == 0
- && nexts->owner->usrdata != NULL
- && !(((lang_input_statement_type *) nexts->owner->usrdata)
- ->flags.just_syms))
- flags = (((flags ^ SEC_READONLY) | (nexts->flags ^ SEC_READONLY))
- ^ SEC_READONLY);
place = NULL;
if ((flags & SEC_ALLOC) == 0)
;
/* Alternate explicit import library for dll's. */
{ "%s.dll.a", FALSE },
/* "libfoo.a" could be either an import lib or a static lib.
- For backwards compatibility, libfoo.a needs to precede
- libfoo.dll and foo.dll in the search. */
+ For backwards compatibility, libfoo.a needs to precede
+ libfoo.dll and foo.dll in the search. */
{ "lib%s.a", FALSE },
/* The 'native' spelling of an import lib name is "foo.lib". */
{ "%s.lib", FALSE },
hll_default,
gld_${EMULATION_NAME}_after_parse,
gld_${EMULATION_NAME}_after_open,
+ after_check_relocs_default,
after_allocation_default,
set_output_arch_default,
ldemul_default_target,