rm -f e${EMULATION_NAME}.c
(echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
fragment <<EOF
-/* Copyright (C) 2006-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2020 Free Software Foundation, Inc.
Written by Kai Tietz, OneVision Software GmbH&CoKg.
This file is part of the GNU Binutils.
#include "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
+#include "ctf-api.h"
#include "getopt.h"
#include "libiberty.h"
#include "filenames.h"
OPTION_INSERT_TIMESTAMP,
OPTION_NO_INSERT_TIMESTAMP,
OPTION_TERMINAL_SERVER_AWARE,
- OPTION_BUILD_ID
+ OPTION_BUILD_ID,
+ OPTION_ENABLE_RELOC_SECTION
};
static void
{"insert-timestamp", no_argument, NULL, OPTION_INSERT_TIMESTAMP},
{"no-insert-timestamp", no_argument, NULL, OPTION_NO_INSERT_TIMESTAMP},
{"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+ {"enable-reloc-section", no_argument, NULL, OPTION_ENABLE_RELOC_SECTION},
{NULL, no_argument, NULL, 0}
};
#define U(CSTR) \
((is_underscoring () == 0) ? CSTR : "_" CSTR)
-/* Get size of constant string for a possible underscore prefixed
- C visible symbol. */
-#define U_SIZE(CSTR) \
- (sizeof (CSTR) + (is_underscoring () == 0 ? 0 : 1))
-
#define D(field,symbol,def,usc) {&pep.field, sizeof (pep.field), def, symbol, 0, usc}
static definfo init[] =
layout randomization (ASLR)\n"));
fprintf (file, _(" --dynamicbase Image base address may be relocated using\n\
address space layout randomization (ASLR)\n"));
+ fprintf (file, _(" --enable-reloc-section Create the base relocation table\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"));
/* Get DLLCharacteristics bits */
case OPTION_HIGH_ENTROPY_VA:
pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA;
- break;
+ /* fall through */
case OPTION_DYNAMIC_BASE:
pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
+ /* fall through */
+ case OPTION_ENABLE_RELOC_SECTION:
+ pep_dll_enable_reloc_section = 1;
break;
case OPTION_FORCE_INTEGRITY:
pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
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;
- }
+ free ((char *) emit_build_id);
+ emit_build_id = NULL;
if (optarg == NULL)
optarg = DEFAULT_BUILD_ID_STYLE;
if (strcmp (optarg, "none"))
after_parse_default ();
}
-/* pep-dll.c directly accesses pep_data_import_dll,
- so it must be defined outside of #ifdef DLL_SUPPORT.
- Note - this variable is deliberately not initialised.
- This allows it to be treated as a common varaible, and only
- exist in one incarnation in a multiple target enabled linker. */
-char * pep_data_import_dll;
-
#ifdef DLL_SUPPORT
static struct bfd_link_hash_entry *pep_undef_found_sym;
}
}
-static int
-make_import_fixup (arelent *rel, asection *s, char *name)
+static void
+make_import_fixup (arelent *rel, asection *s, char *name, const char *symname)
{
struct bfd_symbol *sym = *rel->sym_ptr_ptr;
char addend[8];
printf (" pcrel");
printf (" %d bit rel.\n", (int) rel->howto->bitsize);
}
- pep_create_import_fixup (rel, s, _addend, name);
-
- return 1;
-}
-
-static void
-pep_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;
-
- 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)
- {
- char *impname;
-
- if (pep_dll_extra_pe_debug)
- printf ("%s:%s\n", __FUNCTION__, 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, impname, 0, 0, 1);
-
- if (sym && sym->type == bfd_link_hash_defined)
- {
- bfd *b = sym->u.def.section->owner;
- asymbol **symbols;
- int nsyms, i;
-
- if (!bfd_generic_link_read_symbols (b))
- {
- einfo (_("%F%P: %pB: could not read symbols: %E\n"), b);
- return;
- }
-
- symbols = bfd_get_outsymbols (b);
- nsyms = bfd_get_symcount (b);
-
- for (i = 0; i < nsyms; i++)
- {
- if (! CONST_STRNEQ (symbols[i]->name, U ("_head_")))
- continue;
- if (pep_dll_extra_pe_debug)
- printf ("->%s\n", symbols[i]->name);
-
- pep_data_import_dll = (char *) (symbols[i]->name
- + U_SIZE ("_head_") - 1);
- break;
- }
-
- pep_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 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);
+ pep_create_import_fixup (rel, s, _addend, name, symname);
}
static bfd_boolean
bfd_hash_traverse (&link_info.hash->table, pr_sym, NULL);
for (a = link_info.input_bfds; a; a = a->link.next)
- printf ("*%s\n",a->filename);
+ printf ("*%s\n", bfd_get_filename (a));
}
#endif
FIXME: This should be done via a function, rather than by
including an internal BFD header. */
- if (coff_data (link_info.output_bfd) == NULL
+ if (bfd_get_flavour (link_info.output_bfd) != bfd_target_coff_flavour
+ || 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 '%pB'\n"),
link_info.output_bfd);
pe_data (link_info.output_bfd)->pe_opthdr = pep;
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;
+ if (insert_timestamp)
+ pe_data (link_info.output_bfd)->timestamp = -1;
+ else
+ pe_data (link_info.output_bfd)->timestamp = 0;
/* At this point we must decide whether to use long section names
in the output or not. If the user hasn't explicitly specified
pep_output_file_set_long_section_names (link_info.output_bfd);
#ifdef DLL_SUPPORT
- if (pep_enable_stdcall_fixup) /* -1=warn or 1=disable */
- pep_fixup_stdcalls ();
-
pep_process_import_defs (link_info.output_bfd, &link_info);
- pep_find_data_imports ();
+ if (link_info.pei386_auto_import) /* -1=warn or 1=enable */
+ pep_find_data_imports (U ("_head_"), make_import_fixup);
- /* As possibly new symbols are added by imports, we rerun
- stdcall/fastcall fixup here. */
- if (pep_enable_stdcall_fixup) /* -1=warn or 1=disable */
+ /* The implementation of the feature is rather dumb and would cause the
+ compilation time to go through the roof if there are many undefined
+ symbols in the link, so it needs to be run after auto-import. */
+ if (pep_enable_stdcall_fixup) /* -1=warn or 1=enable */
pep_fixup_stdcalls ();
#ifndef TARGET_IS_i386pep
{
struct bfd_symbol *s;
struct bfd_link_hash_entry * blhe;
- char *other_bfd_filename;
- char *n;
+ const char *other_bfd_filename;
s = (relocs[i]->sym_ptr_ptr)[0];
continue;
/* Rename this implib to match the other one. */
- n = xmalloc (strlen (other_bfd_filename) + 1);
- strcpy (n, other_bfd_filename);
- is->the_bfd->my_archive->filename = n;
+ if (!bfd_set_filename (is->the_bfd->my_archive,
+ other_bfd_filename))
+ einfo ("%F%P: %pB: %E\n", is->the_bfd);
}
free (relocs);
members, so look for the first element with a .dll
extension, and use that for the remainder of the
comparisons. */
- pnt = strrchr (is3->the_bfd->filename, '.');
+ pnt = strrchr (bfd_get_filename (is3->the_bfd), '.');
if (pnt != NULL && filename_cmp (pnt, ".dll") == 0)
break;
}
{
/* Skip static members, ie anything with a .obj
extension. */
- pnt = strrchr (is2->the_bfd->filename, '.');
+ pnt = strrchr (bfd_get_filename (is2->the_bfd), '.');
if (pnt != NULL && filename_cmp (pnt, ".obj") == 0)
continue;
- if (filename_cmp (is3->the_bfd->filename,
- is2->the_bfd->filename))
+ if (filename_cmp (bfd_get_filename (is3->the_bfd),
+ bfd_get_filename (is2->the_bfd)))
{
is_ms_arch = 0;
break;
/* This fragment might have come from an .obj file in a Microsoft
import, and not an actual import record. If this is the case,
then leave the filename alone. */
- pnt = strrchr (is->the_bfd->filename, '.');
+ pnt = strrchr (bfd_get_filename (is->the_bfd), '.');
if (is_ms_arch && (filename_cmp (pnt, ".dll") == 0))
{
else /* sentinel */
seq = 'c';
- new_name = xmalloc (strlen (is->the_bfd->filename) + 3);
- sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);
- is->the_bfd->filename = new_name;
-
- new_name = xmalloc (strlen (is->filename) + 3);
- sprintf (new_name, "%s.%c", is->filename, seq);
- is->filename = new_name;
+ new_name
+ = xmalloc (strlen (bfd_get_filename (is->the_bfd)) + 3);
+ sprintf (new_name, "%s.%c",
+ bfd_get_filename (is->the_bfd), seq);
+ is->filename = bfd_set_filename (is->the_bfd, new_name);
+ free (new_name);
+ if (!is->filename)
+ einfo ("%F%P: %pB: %E\n", is->the_bfd);
}
}
}
#ifdef DLL_SUPPORT
if (bfd_link_pic (&link_info)
+ || pep_dll_enable_reloc_section
|| (!bfd_link_relocatable (&link_info)
&& pep_def_file->num_exports != 0))
{
&& (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))
+ && !bfd_input_just_syms (nexts->owner))
flags = (((flags ^ SEC_READONLY)
| (nexts->flags ^ SEC_READONLY))
^ SEC_READONLY);
NULL);
if (after == NULL)
/* *ABS* is always the first output section statement. */
- after = (&lang_output_section_statement.head
- ->output_section_statement);
+ after = (void *) lang_os_list.head;
}
/* All sections in an executable must be aligned to a page boundary.
&add_child);
if (bfd_link_relocatable (&link_info))
{
- os->section_alignment = s->alignment_power;
+ os->section_alignment = exp_intop (1U << s->alignment_power);
os->bfd_section->alignment_power = s->alignment_power;
}
}
ls = &(*pl)->input_section;
- lname = bfd_get_section_name (ls->section->owner, ls->section);
+ lname = bfd_section_name (ls->section);
if (strchr (lname, '\$') != NULL
&& (dollar == NULL || strcmp (orig_secname, lname) < 0))
break;
gld_${EMULATION_NAME}_after_parse,
gld_${EMULATION_NAME}_after_open,
after_check_relocs_default,
+ before_place_orphans_default,
after_allocation_default,
set_output_arch_default,
ldemul_default_target,
gld_${EMULATION_NAME}_recognized_file,
gld_${EMULATION_NAME}_find_potential_libraries,
NULL, /* new_vers_pattern. */
- NULL /* extra_map_file_text */
+ NULL, /* extra_map_file_text */
+ ${LDEMUL_EMIT_CTF_EARLY-NULL},
+ ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
+ ${LDEMUL_PRINT_SYMBOL-NULL}
};
EOF