mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-05 15:15:42 +00:00
BFD linker: Allow target backends to provide alternate entry names.
PR 30144
This commit is contained in:
@@ -36,6 +36,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
|
|||||||
${LDEMUL_EMIT_CTF_EARLY-NULL},
|
${LDEMUL_EMIT_CTF_EARLY-NULL},
|
||||||
${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
|
${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL},
|
||||||
${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
|
${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL},
|
||||||
${LDEMUL_PRINT_SYMBOL-NULL}
|
${LDEMUL_PRINT_SYMBOL-NULL},
|
||||||
|
${LDEMUL_FIND_START_SYMBOL-NULL}
|
||||||
};
|
};
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
@@ -2448,6 +2448,55 @@ gld${EMULATION_NAME}_find_potential_libraries
|
|||||||
{
|
{
|
||||||
return ldfile_open_file_search (name, entry, "", ".lib");
|
return ldfile_open_file_search (name, entry, "", ".lib");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct bfd_link_hash_entry *
|
||||||
|
gld${EMULATION_NAME}_find_alt_start_symbol
|
||||||
|
(struct bfd_sym_chain *entry)
|
||||||
|
{
|
||||||
|
#if defined (TARGET_IS_i386pe)
|
||||||
|
bool entry_has_stdcall_suffix;
|
||||||
|
#endif
|
||||||
|
struct bfd_link_hash_entry *h;
|
||||||
|
size_t entry_name_len;
|
||||||
|
char *symbol_name;
|
||||||
|
const char *prefix;
|
||||||
|
const char *suffix;
|
||||||
|
|
||||||
|
entry_name_len = strlen (entry->name);
|
||||||
|
|
||||||
|
if (is_underscoring ())
|
||||||
|
prefix = "_";
|
||||||
|
else
|
||||||
|
prefix = "";
|
||||||
|
|
||||||
|
#if defined (TARGET_IS_i386pe)
|
||||||
|
if ((entry_name_len > 2 && entry->name[entry_name_len-2] == '@' && ISDIGIT (entry->name[entry_name_len-1]))
|
||||||
|
|| (entry_name_len > 3 && entry->name[entry_name_len-3] == '@' && ISDIGIT (entry->name[entry_name_len-2]) && ISDIGIT (entry->name[entry_name_len-1]))
|
||||||
|
|| (entry_name_len > 4 && entry->name[entry_name_len-4] == '@' && ISDIGIT (entry->name[entry_name_len-3]) && ISDIGIT (entry->name[entry_name_len-2]) && ISDIGIT (entry->name[entry_name_len-1])))
|
||||||
|
entry_has_stdcall_suffix = true;
|
||||||
|
else
|
||||||
|
entry_has_stdcall_suffix = false;
|
||||||
|
|
||||||
|
if (!entry_has_stdcall_suffix && (bfd_link_dll (&link_info) || dll))
|
||||||
|
suffix = "@12";
|
||||||
|
else if (!entry_has_stdcall_suffix && pe_subsystem == 1 /* NT kernel driver */)
|
||||||
|
suffix = "@8";
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
suffix = "";
|
||||||
|
|
||||||
|
if (*prefix == '\0' && *suffix == '\0')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
symbol_name = xmalloc (entry_name_len + 5);
|
||||||
|
strcpy (symbol_name, prefix);
|
||||||
|
strcat (symbol_name, entry->name);
|
||||||
|
strcat (symbol_name, suffix);
|
||||||
|
|
||||||
|
h = bfd_link_hash_lookup (link_info.hash, symbol_name, false, false, true);
|
||||||
|
free (symbol_name);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
gld${EMULATION_NAME}_get_script (int *isfile)
|
gld${EMULATION_NAME}_get_script (int *isfile)
|
||||||
@@ -2526,5 +2575,6 @@ LDEMUL_UNRECOGNIZED_FILE=gld${EMULATION_NAME}_unrecognized_file
|
|||||||
LDEMUL_LIST_OPTIONS=gld${EMULATION_NAME}_list_options
|
LDEMUL_LIST_OPTIONS=gld${EMULATION_NAME}_list_options
|
||||||
LDEMUL_RECOGNIZED_FILE=gld${EMULATION_NAME}_recognized_file
|
LDEMUL_RECOGNIZED_FILE=gld${EMULATION_NAME}_recognized_file
|
||||||
LDEMUL_FIND_POTENTIAL_LIBRARIES=gld${EMULATION_NAME}_find_potential_libraries
|
LDEMUL_FIND_POTENTIAL_LIBRARIES=gld${EMULATION_NAME}_find_potential_libraries
|
||||||
|
LDEMUL_FIND_START_SYMBOL=gld${EMULATION_NAME}_find_alt_start_symbol
|
||||||
|
|
||||||
source_em ${srcdir}/emultempl/emulation.em
|
source_em ${srcdir}/emultempl/emulation.em
|
||||||
|
|||||||
@@ -531,7 +531,9 @@ named @var{entry}, the linker will try to parse @var{entry} as a number,
|
|||||||
and use that as the entry address (the number will be interpreted in
|
and use that as the entry address (the number will be interpreted in
|
||||||
base 10; you may use a leading @samp{0x} for base 16, or a leading
|
base 10; you may use a leading @samp{0x} for base 16, or a leading
|
||||||
@samp{0} for base 8). @xref{Entry Point}, for a discussion of defaults
|
@samp{0} for base 8). @xref{Entry Point}, for a discussion of defaults
|
||||||
and other ways of specifying the entry point.
|
and other ways of specifying the entry point. For i386 PE, @var{entry}
|
||||||
|
can be also the original function name (without the leading underscore
|
||||||
|
and/or the trailing stdcall @samp{@@number} when applicable).
|
||||||
|
|
||||||
@kindex --exclude-libs
|
@kindex --exclude-libs
|
||||||
@item --exclude-libs @var{lib},@var{lib},...
|
@item --exclude-libs @var{lib},@var{lib},...
|
||||||
|
|||||||
@@ -35,6 +35,14 @@
|
|||||||
|
|
||||||
static ld_emulation_xfer_type *ld_emulation;
|
static ld_emulation_xfer_type *ld_emulation;
|
||||||
|
|
||||||
|
struct bfd_link_hash_entry *
|
||||||
|
ldemul_find_alt_start_symbol (struct bfd_sym_chain *entry)
|
||||||
|
{
|
||||||
|
if (ld_emulation->find_alt_start_symbol)
|
||||||
|
return ld_emulation->find_alt_start_symbol (entry);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ldemul_hll (char *name)
|
ldemul_hll (char *name)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -115,9 +115,10 @@ extern void ldemul_acquire_strings_for_ctf
|
|||||||
(struct ctf_dict *, struct elf_strtab_hash *);
|
(struct ctf_dict *, struct elf_strtab_hash *);
|
||||||
extern void ldemul_new_dynsym_for_ctf
|
extern void ldemul_new_dynsym_for_ctf
|
||||||
(struct ctf_dict *, int symidx, struct elf_internal_sym *);
|
(struct ctf_dict *, int symidx, struct elf_internal_sym *);
|
||||||
|
|
||||||
extern bool ldemul_print_symbol
|
extern bool ldemul_print_symbol
|
||||||
(struct bfd_link_hash_entry *hash_entry, void *ptr);
|
(struct bfd_link_hash_entry *hash_entry, void *ptr);
|
||||||
|
extern struct bfd_link_hash_entry * ldemul_find_alt_start_symbol
|
||||||
|
(struct bfd_sym_chain *);
|
||||||
|
|
||||||
typedef struct ld_emulation_xfer_struct {
|
typedef struct ld_emulation_xfer_struct {
|
||||||
/* Run before parsing the command line and script file.
|
/* Run before parsing the command line and script file.
|
||||||
@@ -259,6 +260,11 @@ typedef struct ld_emulation_xfer_struct {
|
|||||||
bool (*print_symbol)
|
bool (*print_symbol)
|
||||||
(struct bfd_link_hash_entry *hash_entry, void *ptr);
|
(struct bfd_link_hash_entry *hash_entry, void *ptr);
|
||||||
|
|
||||||
|
/* Called when ENTRY->name cannot be found by a direct lookup in INFO->hash.
|
||||||
|
Allows emulations to try variations of the name. */
|
||||||
|
struct bfd_link_hash_entry * (*find_alt_start_symbol)
|
||||||
|
(struct bfd_sym_chain *entry);
|
||||||
|
|
||||||
} ld_emulation_xfer_type;
|
} ld_emulation_xfer_type;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
34
ld/ldlang.c
34
ld/ldlang.c
@@ -2485,12 +2485,19 @@ lang_map (void)
|
|||||||
config.map_file);
|
config.map_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_defined (struct bfd_link_hash_entry *h)
|
||||||
|
{
|
||||||
|
return h != NULL
|
||||||
|
&& (h->type == bfd_link_hash_defined
|
||||||
|
|| h->type == bfd_link_hash_defweak);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
sort_def_symbol (struct bfd_link_hash_entry *hash_entry,
|
sort_def_symbol (struct bfd_link_hash_entry *hash_entry,
|
||||||
void *info ATTRIBUTE_UNUSED)
|
void *info ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
if ((hash_entry->type == bfd_link_hash_defined
|
if (is_defined (hash_entry)
|
||||||
|| hash_entry->type == bfd_link_hash_defweak)
|
|
||||||
&& hash_entry->u.def.section->owner != link_info.output_bfd
|
&& hash_entry->u.def.section->owner != link_info.output_bfd
|
||||||
&& hash_entry->u.def.section->owner != NULL)
|
&& hash_entry->u.def.section->owner != NULL)
|
||||||
{
|
{
|
||||||
@@ -4184,9 +4191,7 @@ ldlang_check_require_defined_symbols (void)
|
|||||||
|
|
||||||
h = bfd_link_hash_lookup (link_info.hash, ptr->name,
|
h = bfd_link_hash_lookup (link_info.hash, ptr->name,
|
||||||
false, false, true);
|
false, false, true);
|
||||||
if (h == NULL
|
if (! is_defined (h))
|
||||||
|| (h->type != bfd_link_hash_defined
|
|
||||||
&& h->type != bfd_link_hash_defweak))
|
|
||||||
einfo(_("%X%P: required symbol `%s' not defined\n"), ptr->name);
|
einfo(_("%X%P: required symbol `%s' not defined\n"), ptr->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4892,9 +4897,7 @@ print_assignment (lang_assignment_statement_type *assignment,
|
|||||||
|
|
||||||
h = bfd_link_hash_lookup (link_info.hash, assignment->exp->assign.dst,
|
h = bfd_link_hash_lookup (link_info.hash, assignment->exp->assign.dst,
|
||||||
false, false, true);
|
false, false, true);
|
||||||
if (h != NULL
|
if (is_defined (h))
|
||||||
&& (h->type == bfd_link_hash_defined
|
|
||||||
|| h->type == bfd_link_hash_defweak))
|
|
||||||
{
|
{
|
||||||
value = h->u.def.value;
|
value = h->u.def.value;
|
||||||
value += h->u.def.section->output_section->vma;
|
value += h->u.def.section->output_section->vma;
|
||||||
@@ -4939,8 +4942,7 @@ print_one_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr)
|
|||||||
{
|
{
|
||||||
asection *sec = (asection *) ptr;
|
asection *sec = (asection *) ptr;
|
||||||
|
|
||||||
if ((hash_entry->type == bfd_link_hash_defined
|
if (is_defined (hash_entry)
|
||||||
|| hash_entry->type == bfd_link_hash_defweak)
|
|
||||||
&& sec == hash_entry->u.def.section)
|
&& sec == hash_entry->u.def.section)
|
||||||
{
|
{
|
||||||
print_spaces (SECTION_NAME_MAP_LENGTH);
|
print_spaces (SECTION_NAME_MAP_LENGTH);
|
||||||
@@ -7234,9 +7236,7 @@ lang_end (void)
|
|||||||
{
|
{
|
||||||
h = bfd_link_hash_lookup (link_info.hash, sym->name,
|
h = bfd_link_hash_lookup (link_info.hash, sym->name,
|
||||||
false, false, false);
|
false, false, false);
|
||||||
if (h != NULL
|
if (is_defined (h)
|
||||||
&& (h->type == bfd_link_hash_defined
|
|
||||||
|| h->type == bfd_link_hash_defweak)
|
|
||||||
&& !bfd_is_const_section (h->u.def.section))
|
&& !bfd_is_const_section (h->u.def.section))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -7255,9 +7255,11 @@ lang_end (void)
|
|||||||
|
|
||||||
h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name,
|
h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name,
|
||||||
false, false, true);
|
false, false, true);
|
||||||
if (h != NULL
|
|
||||||
&& (h->type == bfd_link_hash_defined
|
if (! is_defined (h) || h->u.def.section->output_section == NULL)
|
||||||
|| h->type == bfd_link_hash_defweak)
|
h = ldemul_find_alt_start_symbol (&entry_symbol);
|
||||||
|
|
||||||
|
if (is_defined (h)
|
||||||
&& h->u.def.section->output_section != NULL)
|
&& h->u.def.section->output_section != NULL)
|
||||||
{
|
{
|
||||||
bfd_vma val;
|
bfd_vma val;
|
||||||
|
|||||||
Reference in New Issue
Block a user