mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
2 Commits
efbd9add96
...
users/hjl/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16526e42c2 | ||
|
|
316b611580 |
@@ -2339,6 +2339,9 @@ extern bfd_boolean bfd_elf_gc_common_final_link
|
|||||||
extern asection *_bfd_elf_is_start_stop
|
extern asection *_bfd_elf_is_start_stop
|
||||||
(const struct bfd_link_info *, struct elf_link_hash_entry *);
|
(const struct bfd_link_info *, struct elf_link_hash_entry *);
|
||||||
|
|
||||||
|
extern void _bfd_elf_record_start_stop
|
||||||
|
(const struct bfd_link_info *);
|
||||||
|
|
||||||
extern bfd_boolean bfd_elf_reloc_symbol_deleted_p
|
extern bfd_boolean bfd_elf_reloc_symbol_deleted_p
|
||||||
(bfd_vma, void *);
|
(bfd_vma, void *);
|
||||||
|
|
||||||
|
|||||||
@@ -13791,3 +13791,24 @@ elf_append_rel (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
|
|||||||
BFD_ASSERT (loc + bed->s->sizeof_rel <= s->contents + s->size);
|
BFD_ASSERT (loc + bed->s->sizeof_rel <= s->contents + s->size);
|
||||||
bed->s->swap_reloc_out (abfd, rel, loc);
|
bed->s->swap_reloc_out (abfd, rel, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For undefined __start_<name> and __stop_<name> symbols, set
|
||||||
|
def_regular to 1. This is called via elf_link_hash_traverse. */
|
||||||
|
|
||||||
|
static bfd_boolean
|
||||||
|
elf_link_record_start_stop (struct elf_link_hash_entry *h, void *data)
|
||||||
|
{
|
||||||
|
const struct bfd_link_info * info
|
||||||
|
= (const struct bfd_link_info *) data;
|
||||||
|
if (_bfd_elf_is_start_stop (info, h) != NULL)
|
||||||
|
h->def_regular = 1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_bfd_elf_record_start_stop (const struct bfd_link_info * info)
|
||||||
|
{
|
||||||
|
elf_link_hash_traverse (elf_hash_table (info),
|
||||||
|
elf_link_record_start_stop,
|
||||||
|
(void *) info);
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ static void gld${EMULATION_NAME}_after_parse (void);
|
|||||||
static void gld${EMULATION_NAME}_after_open (void);
|
static void gld${EMULATION_NAME}_after_open (void);
|
||||||
static void gld${EMULATION_NAME}_before_allocation (void);
|
static void gld${EMULATION_NAME}_before_allocation (void);
|
||||||
static void gld${EMULATION_NAME}_after_allocation (void);
|
static void gld${EMULATION_NAME}_after_allocation (void);
|
||||||
|
static void gld${EMULATION_NAME}_restore_ehdr_start (void);
|
||||||
static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
|
static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
|
||||||
(asection *, const char *, int);
|
(asection *, const char *, int);
|
||||||
EOF
|
EOF
|
||||||
@@ -1330,6 +1331,7 @@ fragment <<EOF
|
|||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test x"$LDEMUL_RECORD_LINK_ASSIGNMENTS" != xgld"$EMULATION_NAME"_record_link_assignments; then
|
||||||
fragment <<EOF
|
fragment <<EOF
|
||||||
|
|
||||||
/* Look through an expression for an assignment statement. */
|
/* Look through an expression for an assignment statement. */
|
||||||
@@ -1398,7 +1400,79 @@ gld${EMULATION_NAME}_find_statement_assignment (lang_statement_union_type *s)
|
|||||||
gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
|
gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct elf_link_hash_entry *ehdr_start;
|
||||||
|
static struct bfd_link_hash_entry ehdr_start_save;
|
||||||
|
|
||||||
|
static void
|
||||||
|
gld${EMULATION_NAME}_record_link_assignments (lang_phase_type phase)
|
||||||
|
{
|
||||||
|
if (phase == lang_mark_phase_enum
|
||||||
|
&& is_elf_hash_table (link_info.hash))
|
||||||
|
{
|
||||||
|
/* Make __ehdr_start hidden if it has been referenced, to
|
||||||
|
prevent the symbol from being dynamic. */
|
||||||
|
if (!bfd_link_relocatable (&link_info))
|
||||||
|
{
|
||||||
|
struct elf_link_hash_entry *h
|
||||||
|
= elf_link_hash_lookup (elf_hash_table (&link_info),
|
||||||
|
"__ehdr_start", FALSE, FALSE, TRUE);
|
||||||
|
|
||||||
|
/* Only adjust the export class if the symbol was referenced
|
||||||
|
and not defined, otherwise leave it alone. */
|
||||||
|
if (h != NULL
|
||||||
|
&& (h->root.type == bfd_link_hash_new
|
||||||
|
|| h->root.type == bfd_link_hash_undefined
|
||||||
|
|| h->root.type == bfd_link_hash_undefweak
|
||||||
|
|| h->root.type == bfd_link_hash_common))
|
||||||
|
{
|
||||||
|
_bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
|
||||||
|
if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
|
||||||
|
h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
|
||||||
|
/* Don't leave the symbol undefined. Undefined hidden
|
||||||
|
symbols typically won't have dynamic relocations, but
|
||||||
|
we most likely will need dynamic relocations for
|
||||||
|
__ehdr_start if we are building a PIE or shared
|
||||||
|
library. */
|
||||||
|
ehdr_start = h;
|
||||||
|
ehdr_start_save = h->root;
|
||||||
|
h->root.type = bfd_link_hash_defined;
|
||||||
|
h->root.u.def.section = bfd_abs_section_ptr;
|
||||||
|
h->root.u.def.value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we are going to make any variable assignments, we need to
|
||||||
|
let the ELF backend know about them in case the variables are
|
||||||
|
referred to by dynamic objects. */
|
||||||
|
lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
|
||||||
|
|
||||||
|
_bfd_elf_record_start_stop (&link_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gld${EMULATION_NAME}_restore_ehdr_start (void)
|
||||||
|
{
|
||||||
|
if (ehdr_start != NULL)
|
||||||
|
{
|
||||||
|
/* If we twiddled __ehdr_start to defined earlier, put it back
|
||||||
|
as it was. */
|
||||||
|
ehdr_start->root.type = ehdr_start_save.type;
|
||||||
|
ehdr_start->root.u = ehdr_start_save.u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
else
|
||||||
|
fragment <<EOF
|
||||||
|
|
||||||
|
static
|
||||||
|
gld${EMULATION_NAME}_restore_ehdr_start (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then
|
if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then
|
||||||
if test x"${ELF_INTERPRETER_NAME+set}" = xset; then
|
if test x"${ELF_INTERPRETER_NAME+set}" = xset; then
|
||||||
@@ -1455,11 +1529,6 @@ gld${EMULATION_NAME}_append_to_separated_string (char **to, char *op_arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__GNUC__) && GCC_VERSION < 4006
|
|
||||||
/* Work around a GCC uninitialized warning bug fixed in GCC 4.6. */
|
|
||||||
static struct bfd_link_hash_entry ehdr_start_empty;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This is called after the sections have been attached to output
|
/* This is called after the sections have been attached to output
|
||||||
sections, but before any sizes or addresses have been set. */
|
sections, but before any sizes or addresses have been set. */
|
||||||
|
|
||||||
@@ -1469,55 +1538,9 @@ gld${EMULATION_NAME}_before_allocation (void)
|
|||||||
const char *rpath;
|
const char *rpath;
|
||||||
asection *sinterp;
|
asection *sinterp;
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
struct elf_link_hash_entry *ehdr_start = NULL;
|
|
||||||
#if defined(__GNUC__) && GCC_VERSION < 4006
|
|
||||||
/* Work around a GCC uninitialized warning bug fixed in GCC 4.6. */
|
|
||||||
struct bfd_link_hash_entry ehdr_start_save = ehdr_start_empty;
|
|
||||||
#else
|
|
||||||
struct bfd_link_hash_entry ehdr_start_save;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (is_elf_hash_table (link_info.hash))
|
if (is_elf_hash_table (link_info.hash))
|
||||||
{
|
_bfd_elf_tls_setup (link_info.output_bfd, &link_info);
|
||||||
_bfd_elf_tls_setup (link_info.output_bfd, &link_info);
|
|
||||||
|
|
||||||
/* Make __ehdr_start hidden if it has been referenced, to
|
|
||||||
prevent the symbol from being dynamic. */
|
|
||||||
if (!bfd_link_relocatable (&link_info))
|
|
||||||
{
|
|
||||||
struct elf_link_hash_entry *h
|
|
||||||
= elf_link_hash_lookup (elf_hash_table (&link_info), "__ehdr_start",
|
|
||||||
FALSE, FALSE, TRUE);
|
|
||||||
|
|
||||||
/* Only adjust the export class if the symbol was referenced
|
|
||||||
and not defined, otherwise leave it alone. */
|
|
||||||
if (h != NULL
|
|
||||||
&& (h->root.type == bfd_link_hash_new
|
|
||||||
|| h->root.type == bfd_link_hash_undefined
|
|
||||||
|| h->root.type == bfd_link_hash_undefweak
|
|
||||||
|| h->root.type == bfd_link_hash_common))
|
|
||||||
{
|
|
||||||
_bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
|
|
||||||
if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
|
|
||||||
h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
|
|
||||||
/* Don't leave the symbol undefined. Undefined hidden
|
|
||||||
symbols typically won't have dynamic relocations, but
|
|
||||||
we most likely will need dynamic relocations for
|
|
||||||
__ehdr_start if we are building a PIE or shared
|
|
||||||
library. */
|
|
||||||
ehdr_start = h;
|
|
||||||
ehdr_start_save = h->root;
|
|
||||||
h->root.type = bfd_link_hash_defined;
|
|
||||||
h->root.u.def.section = bfd_abs_section_ptr;
|
|
||||||
h->root.u.def.value = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we are going to make any variable assignments, we need to
|
|
||||||
let the ELF backend know about them in case the variables are
|
|
||||||
referred to by dynamic objects. */
|
|
||||||
lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Let the ELF backend work out the sizes of any sections required
|
/* Let the ELF backend work out the sizes of any sections required
|
||||||
by dynamic linking. */
|
by dynamic linking. */
|
||||||
@@ -1627,13 +1650,7 @@ ${ELF_INTERPRETER_SET_DEFAULT}
|
|||||||
if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
|
if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
|
||||||
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
|
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
|
||||||
|
|
||||||
if (ehdr_start != NULL)
|
gld${EMULATION_NAME}_restore_ehdr_start ();
|
||||||
{
|
|
||||||
/* If we twiddled __ehdr_start to defined earlier, put it back
|
|
||||||
as it was. */
|
|
||||||
ehdr_start->root.type = ehdr_start_save.type;
|
|
||||||
ehdr_start->root.u = ehdr_start_save.u;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
@@ -2527,6 +2544,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
|
|||||||
${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols},
|
${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols},
|
||||||
${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
|
${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
|
||||||
${LDEMUL_NEW_VERS_PATTERN-NULL},
|
${LDEMUL_NEW_VERS_PATTERN-NULL},
|
||||||
${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL}
|
${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL},
|
||||||
|
${LDEMUL_RECORD_LINK_ASSIGNMENTS-gld${EMULATION_NAME}_record_link_assignments},
|
||||||
};
|
};
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
|
|||||||
NULL, /* recognized file */
|
NULL, /* recognized file */
|
||||||
NULL, /* find_potential_libraries */
|
NULL, /* find_potential_libraries */
|
||||||
NULL, /* new_vers_pattern */
|
NULL, /* new_vers_pattern */
|
||||||
NULL /* extra_map_file_text */
|
NULL, /* extra_map_file_text */
|
||||||
|
NULL /* record_link_assignments */
|
||||||
};
|
};
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
@@ -355,3 +355,10 @@ ldemul_extra_map_file_text (bfd *abfd, struct bfd_link_info *info, FILE *mapf)
|
|||||||
if (ld_emulation->extra_map_file_text)
|
if (ld_emulation->extra_map_file_text)
|
||||||
ld_emulation->extra_map_file_text (abfd, info, mapf);
|
ld_emulation->extra_map_file_text (abfd, info, mapf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ldemul_record_link_assignments (lang_phase_type phase)
|
||||||
|
{
|
||||||
|
if (ld_emulation->record_link_assignments)
|
||||||
|
ld_emulation->record_link_assignments (phase);
|
||||||
|
}
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ extern struct bfd_elf_version_expr *ldemul_new_vers_pattern
|
|||||||
(struct bfd_elf_version_expr *);
|
(struct bfd_elf_version_expr *);
|
||||||
extern void ldemul_extra_map_file_text
|
extern void ldemul_extra_map_file_text
|
||||||
(bfd *, struct bfd_link_info *, FILE *);
|
(bfd *, struct bfd_link_info *, FILE *);
|
||||||
|
extern void ldemul_record_link_assignments
|
||||||
|
(lang_phase_type);
|
||||||
|
|
||||||
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.
|
||||||
@@ -201,6 +203,10 @@ typedef struct ld_emulation_xfer_struct {
|
|||||||
void (*extra_map_file_text)
|
void (*extra_map_file_text)
|
||||||
(bfd *, struct bfd_link_info *, FILE *);
|
(bfd *, struct bfd_link_info *, FILE *);
|
||||||
|
|
||||||
|
/* Called to record link assignments. */
|
||||||
|
void (*record_link_assignments)
|
||||||
|
(lang_phase_type);
|
||||||
|
|
||||||
} ld_emulation_xfer_type;
|
} ld_emulation_xfer_type;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@@ -6930,6 +6930,8 @@ lang_process (void)
|
|||||||
collection in order to make sure that all symbol aliases are resolved. */
|
collection in order to make sure that all symbol aliases are resolved. */
|
||||||
lang_do_assignments (lang_mark_phase_enum);
|
lang_do_assignments (lang_mark_phase_enum);
|
||||||
|
|
||||||
|
ldemul_record_link_assignments (lang_mark_phase_enum);
|
||||||
|
|
||||||
lang_do_memory_regions();
|
lang_do_memory_regions();
|
||||||
expld.phase = lang_first_phase_enum;
|
expld.phase = lang_first_phase_enum;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user