* ldemul.h (ld_emulation_xfer_struct): new hook "recognized_file"
* ldemul.c (ldemul_recognized_file): new function, new hook * ldint.texinfo: document new hook. * ldlang.c (load_symbols): call recognized_hook for all objects we do recognize, in case the emulation needs to handle them specially. PE DLLs use this. * pe-dll.c (pe_dll_generate_def_file): take out hack and debug printfs * emultempl/pe.em (gld_i386_recognized_file): new function (gld_i486_unrecognized_file): take out hack
This commit is contained in:
parent
8cde3351e4
commit
f1b2a4d619
13
ld/ChangeLog
13
ld/ChangeLog
|
@ -1,3 +1,16 @@
|
|||
1998-11-25 DJ Delorie <dj@cygnus.com>
|
||||
|
||||
* ldemul.h (ld_emulation_xfer_struct): new hook "recognized_file"
|
||||
* ldemul.c (ldemul_recognized_file): new function, new hook
|
||||
* ldint.texinfo: document new hook.
|
||||
* ldlang.c (load_symbols): call recognized_hook for all objects we
|
||||
do recognize, in case the emulation needs to handle them
|
||||
specially. PE DLLs use this.
|
||||
* pe-dll.c (pe_dll_generate_def_file): take out hack and debug
|
||||
printfs
|
||||
* emultempl/pe.em (gld_i386_recognized_file): new function
|
||||
(gld_i486_unrecognized_file): take out hack
|
||||
|
||||
start-sanitize-vr4xxx
|
||||
1998-11-24 Gavin Romig-Koch <gavin@cygnus.com>
|
||||
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/* ld-emul.h - Linker emulation header file
|
||||
Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GLD, the Gnu Linker.
|
||||
|
||||
GLD is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GLD is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details. */
|
||||
|
||||
#ifndef LDEMUL_H
|
||||
#define LDEMUL_H
|
||||
|
||||
#if ANSI_PROTOTYPES
|
||||
struct lang_input_statement_struct;
|
||||
struct search_dirs;
|
||||
#endif
|
||||
|
||||
extern void ldemul_hll PARAMS ((char *));
|
||||
extern void ldemul_syslib PARAMS ((char *));
|
||||
extern void ldemul_after_parse PARAMS ((void));
|
||||
extern void ldemul_before_parse PARAMS ((void));
|
||||
extern void ldemul_after_open PARAMS ((void));
|
||||
extern void ldemul_after_allocation PARAMS ((void));
|
||||
extern void ldemul_before_allocation PARAMS ((void));
|
||||
extern void ldemul_set_output_arch PARAMS ((void));
|
||||
extern char *ldemul_choose_target PARAMS ((void));
|
||||
extern void ldemul_choose_mode PARAMS ((char *));
|
||||
extern void ldemul_list_emulations PARAMS ((FILE *));
|
||||
extern void ldemul_list_emulation_options PARAMS ((FILE *));
|
||||
extern char *ldemul_get_script PARAMS ((int *isfile));
|
||||
extern void ldemul_finish PARAMS ((void));
|
||||
extern void ldemul_set_symbols PARAMS ((void));
|
||||
extern void ldemul_create_output_section_statements PARAMS ((void));
|
||||
extern boolean ldemul_place_orphan
|
||||
PARAMS ((struct lang_input_statement_struct *, asection *));
|
||||
extern int ldemul_parse_args PARAMS ((int, char **));
|
||||
extern boolean ldemul_unrecognized_file
|
||||
PARAMS ((struct lang_input_statement_struct *));
|
||||
extern boolean ldemul_open_dynamic_archive
|
||||
PARAMS ((const char *, struct search_dirs *,
|
||||
struct lang_input_statement_struct *));
|
||||
extern char *ldemul_default_target PARAMS ((void));
|
||||
extern void after_parse_default PARAMS ((void));
|
||||
extern void after_open_default PARAMS ((void));
|
||||
extern void after_allocation_default PARAMS ((void));
|
||||
extern void before_allocation_default PARAMS ((void));
|
||||
extern void set_output_arch_default PARAMS ((void));
|
||||
extern void syslib_default PARAMS ((char*));
|
||||
extern void hll_default PARAMS ((char*));
|
||||
|
||||
typedef struct ld_emulation_xfer_struct
|
||||
{
|
||||
/* Run before parsing the command line and script file.
|
||||
Set the architecture, maybe other things. */
|
||||
void (*before_parse) PARAMS ((void));
|
||||
|
||||
/* Handle the SYSLIB (low level library) script command. */
|
||||
void (*syslib) PARAMS ((char *));
|
||||
|
||||
/* Handle the HLL (high level library) script command. */
|
||||
void (*hll) PARAMS ((char *));
|
||||
|
||||
/* Run after parsing the command line and script file. */
|
||||
void (*after_parse) PARAMS ((void));
|
||||
|
||||
/* Run after opening all input files, and loading the symbols. */
|
||||
void (*after_open) PARAMS ((void));
|
||||
|
||||
/* Run after allocating output sections. */
|
||||
void (*after_allocation) PARAMS ( (void));
|
||||
|
||||
/* Set the output architecture and machine if possible. */
|
||||
void (*set_output_arch) PARAMS ((void));
|
||||
|
||||
/* Decide which target name to use. */
|
||||
char * (*choose_target) PARAMS ((void));
|
||||
|
||||
/* Run before allocating output sections. */
|
||||
void (*before_allocation) PARAMS ((void));
|
||||
|
||||
/* Return the appropriate linker script. */
|
||||
char * (*get_script) PARAMS ((int *isfile));
|
||||
|
||||
/* The name of this emulation. */
|
||||
char *emulation_name;
|
||||
|
||||
/* The output format. */
|
||||
char *target_name;
|
||||
|
||||
/* Run after assigning values from the script. */
|
||||
void (*finish) PARAMS ((void));
|
||||
|
||||
/* Create any output sections needed by the target. */
|
||||
void (*create_output_section_statements) PARAMS ((void));
|
||||
|
||||
/* Try to open a dynamic library. ARCH is an architecture name, and
|
||||
is normally the empty string. ENTRY is the lang_input_statement
|
||||
that should be opened. */
|
||||
boolean (*open_dynamic_archive)
|
||||
PARAMS ((const char *arch, struct search_dirs *,
|
||||
struct lang_input_statement_struct *entry));
|
||||
|
||||
/* Place an orphan section. Return true if it was placed, false if
|
||||
the default action should be taken. This field may be NULL, in
|
||||
which case the default action will always be taken. */
|
||||
boolean (*place_orphan)
|
||||
PARAMS ((struct lang_input_statement_struct *, asection *));
|
||||
|
||||
/* Run after assigning parsing with the args, but before
|
||||
reading the script. Used to initialize symbols used in the script. */
|
||||
void (*set_symbols) PARAMS ((void));
|
||||
|
||||
/* Run to parse args which the base linker doesn't
|
||||
understand. Return non zero on sucess. */
|
||||
int (*parse_args) PARAMS ((int, char **));
|
||||
|
||||
/* Run to handle files which are not recognized as object files or
|
||||
archives. Return true if the file was handled. */
|
||||
boolean (*unrecognized_file)
|
||||
PARAMS ((struct lang_input_statement_struct *));
|
||||
|
||||
/* Run to list the command line options which parse_args handles. */
|
||||
void (* list_options) PARAMS ((FILE *));
|
||||
|
||||
/* Run to specially handle files which *are* recognized as object
|
||||
files or archives. Return true if the file was handled. */
|
||||
boolean (*recognized_file)
|
||||
PARAMS ((struct lang_input_statement_struct *));
|
||||
|
||||
} ld_emulation_xfer_type;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
intel_ic960_ld_mode_enum,
|
||||
default_mode_enum ,
|
||||
intel_gld960_ld_mode_enum
|
||||
} lang_emulation_mode_enum_type;
|
||||
|
||||
extern ld_emulation_xfer_type *ld_emulations[];
|
||||
|
||||
#endif
|
61
ld/ldlang.c
61
ld/ldlang.c
|
@ -151,6 +151,7 @@ static void lang_gc_wild
|
|||
PARAMS ((lang_wild_statement_type *, const char *, const char *));
|
||||
static void lang_gc_sections_1 PARAMS ((lang_statement_union_type *));
|
||||
static void lang_gc_sections PARAMS ((void));
|
||||
static void lang_do_version_exports_section PARAMS ((void));
|
||||
|
||||
|
||||
/* EXPORTS */
|
||||
|
@ -1253,6 +1254,9 @@ load_symbols (entry, place)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ldemul_recognized_file (entry))
|
||||
return;
|
||||
|
||||
/* We don't call ldlang_add_file for an archive. Instead, the
|
||||
add_symbols entry point will call ldlang_add_file, via the
|
||||
add_archive_element callback, for each element of the archive
|
||||
|
@ -2089,7 +2093,10 @@ print_statement (s, os)
|
|||
case lang_constructors_statement_enum:
|
||||
if (constructor_list.head != NULL)
|
||||
{
|
||||
minfo (" CONSTRUCTORS\n");
|
||||
if (constructors_sorted)
|
||||
minfo (" SORT (CONSTRUCTORS)\n");
|
||||
else
|
||||
minfo (" CONSTRUCTORS\n");
|
||||
print_statement_list (constructor_list.head, os);
|
||||
}
|
||||
break;
|
||||
|
@ -3549,6 +3556,8 @@ lang_gc_sections_1 (s)
|
|||
case lang_group_statement_enum:
|
||||
lang_gc_sections_1 (s->group_statement.children.head);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3567,7 +3576,7 @@ lang_gc_sections ()
|
|||
Handle the entry symbol at the same time. */
|
||||
|
||||
fake_list_start.next = ldlang_undef_chain_list_head;
|
||||
fake_list_start.name = entry_symbol;
|
||||
fake_list_start.name = (char *) entry_symbol;
|
||||
|
||||
for (ulist = &fake_list_start; ulist; ulist = ulist->next)
|
||||
{
|
||||
|
@ -3612,6 +3621,10 @@ lang_process ()
|
|||
link. */
|
||||
lang_check ();
|
||||
|
||||
/* Handle .exports instead of a version script if we're told to do so. */
|
||||
if (command_line.version_exports_section)
|
||||
lang_do_version_exports_section ();
|
||||
|
||||
/* Build all sets based on the information gathered from the input
|
||||
files. */
|
||||
ldctor_build_sets ();
|
||||
|
@ -3655,6 +3668,10 @@ lang_process ()
|
|||
|
||||
relax_again = false;
|
||||
|
||||
/* Note: pe-dll.c does something like this also. If you find
|
||||
you need to change this code, you probably need to change
|
||||
pe-dll.c also. DJ */
|
||||
|
||||
/* Do all the assignments with our current guesses as to
|
||||
section sizes. */
|
||||
lang_do_assignments (statement_list.head,
|
||||
|
@ -3836,7 +3853,7 @@ lang_add_reloc (reloc, howto, section, name, addend)
|
|||
p->output_vma = 0;
|
||||
}
|
||||
|
||||
void
|
||||
lang_assignment_statement_type *
|
||||
lang_add_assignment (exp)
|
||||
etree_type * exp;
|
||||
{
|
||||
|
@ -3844,6 +3861,7 @@ lang_add_assignment (exp)
|
|||
stat_ptr);
|
||||
|
||||
new->exp = exp;
|
||||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4476,3 +4494,40 @@ lang_add_vers_depend (list, name)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
lang_do_version_exports_section ()
|
||||
{
|
||||
struct bfd_elf_version_expr *greg = NULL, *lreg;
|
||||
|
||||
LANG_FOR_EACH_INPUT_STATEMENT (is)
|
||||
{
|
||||
asection *sec = bfd_get_section_by_name (is->the_bfd, ".exports");
|
||||
char *contents, *p;
|
||||
bfd_size_type len;
|
||||
|
||||
if (sec == NULL)
|
||||
continue;
|
||||
|
||||
len = bfd_section_size (is->the_bfd, sec);
|
||||
contents = xmalloc (len);
|
||||
if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len))
|
||||
einfo (_("%X%P: unable to read .exports section contents"), sec);
|
||||
|
||||
while (p < contents+len)
|
||||
{
|
||||
greg = lang_new_vers_regex (greg, p);
|
||||
p = strchr (p, '\0') + 1;
|
||||
}
|
||||
|
||||
free (contents);
|
||||
|
||||
/* Do not include this section in the link. */
|
||||
bfd_set_section_flags (is->the_bfd, sec,
|
||||
bfd_get_section_flags (is->the_bfd, sec) | SEC_EXCLUDE);
|
||||
}
|
||||
|
||||
lreg = lang_new_vers_regex (NULL, "*");
|
||||
lang_register_vers_node (command_line.version_exports_section,
|
||||
lang_new_vers_node (greg, lreg), NULL);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue