* elf32-spu.c (struct spu_link_hash_table): Add stack_analysis
	and emit_stack_syms bitfields.
	(get_sym_h): Read all symbols if stack analysis will be done.
	(spu_elf_create_sections): Add stack_analysis and emit_stack_syms
	params, and stash in hash table.
	(is_hint): Split off from..
	(is_branch): ..here.  Adjust callers.
	(spu_elf_size_stubs): Add stack_analysis param.  Arrange to read
	and keep all syms.
	(write_one_stub): Fix mem leak.
	(find_function_stack_adjust): New function.
	(sort_syms_syms, sort_syms_psecs): New vars.
	(sort_syms): New function.
	(struct call_info, struct function_info): New.
	(struct spu_elf_stack_info): New.
	(alloc_stack_info, maybe_insert_function, func_name): New functions.
	(is_nop, insns_at_end, check_function_ranges): Likewise.
	(find_function, insert_callee, mark_functions_via_relocs): Likewise.
	(pasted_function, interesting_section, discover_functions): Likewise.
	(mark_non_root, call_graph_traverse, build_call_tree): Likewise.
	(sum_stack, spu_elf_stack_analysis, spu_elf_final_link): Likewise.
	(bfd_elf32_bfd_final_link): Define.
	* elf32-spu.h (struct _spu_elf_section_data): Add stack_info field.
	(spu_elf_create_sections, spu_elf_size_stubs): Update prototypes.
include/
	* bfdlink.h (struct bfd_link_info): Add "info" and "minfo".
ld/
	* ldmain.c (link_callbacks): Init info and minfo fields.
	* ldmisc.c (minfo): Do nothing if no map file.
	* emultempl/spuelf.em (stack_analysis, emit_stack_syms): New vars.
	(spu_after_open): Adjust spu_elf_create_sections call.
	(spu_before_allocation): Likewise for spu_elf_size_stubs.
	(OPTION_SPU_STACK_ANALYSIS, OPTION_SPU_STACK_SYMS): Define.
	(PARSE_AND_LIST_LONGOPTS): Add new entries.
	(PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Likewise.
	* gen-doc.texi: Add @set for SPU and other missing targets.
	* ld.texinfo: Update man page selection to match gen-doc.texi.
	Document SPU features.
This commit is contained in:
Alan Modra 2007-04-30 14:06:40 +00:00
parent a540244da6
commit 49fa1e1518
11 changed files with 1441 additions and 49 deletions

View File

@ -1,3 +1,30 @@
2007-04-30 Alan Modra <amodra@bigpond.net.au>
* elf32-spu.c (struct spu_link_hash_table): Add stack_analysis
and emit_stack_syms bitfields.
(get_sym_h): Read all symbols if stack analysis will be done.
(spu_elf_create_sections): Add stack_analysis and emit_stack_syms
params, and stash in hash table.
(is_hint): Split off from..
(is_branch): ..here. Adjust callers.
(spu_elf_size_stubs): Add stack_analysis param. Arrange to read
and keep all syms.
(write_one_stub): Fix mem leak.
(find_function_stack_adjust): New function.
(sort_syms_syms, sort_syms_psecs): New vars.
(sort_syms): New function.
(struct call_info, struct function_info): New.
(struct spu_elf_stack_info): New.
(alloc_stack_info, maybe_insert_function, func_name): New functions.
(is_nop, insns_at_end, check_function_ranges): Likewise.
(find_function, insert_callee, mark_functions_via_relocs): Likewise.
(pasted_function, interesting_section, discover_functions): Likewise.
(mark_non_root, call_graph_traverse, build_call_tree): Likewise.
(sum_stack, spu_elf_stack_analysis, spu_elf_final_link): Likewise.
(bfd_elf32_bfd_final_link): Define.
* elf32-spu.h (struct _spu_elf_section_data): Add stack_info field.
(spu_elf_create_sections, spu_elf_size_stubs): Update prototypes.
2007-04-28 Sergey Rogozhkin <rogozhkin@niisi.msk.ru>
* elfxx-mips.c (mips_elf_create_dynamic_relocation): Don't access

File diff suppressed because it is too large Load Diff

View File

@ -20,10 +20,16 @@
/* Extra info kept for SPU sections. */
struct spu_elf_stack_info;
struct _spu_elf_section_data
{
struct bfd_elf_section_data elf;
/* Stack analysis info kept for this section. */
struct spu_elf_stack_info *stack_info;
/* Non-zero for overlay output sections. */
unsigned int ovl_index;
};
@ -41,9 +47,9 @@ extern void spu_elf_plugin (int);
extern bfd_boolean spu_elf_open_builtin_lib (bfd **,
const struct _ovl_stream *);
extern bfd_boolean spu_elf_create_sections (bfd *,
struct bfd_link_info *);
struct bfd_link_info *, int, int);
extern bfd_boolean spu_elf_find_overlays (bfd *, struct bfd_link_info *);
extern bfd_boolean spu_elf_size_stubs (bfd *, struct bfd_link_info *, int,
extern bfd_boolean spu_elf_size_stubs (bfd *, struct bfd_link_info *, int, int,
asection **, asection **,
asection **);
extern bfd_boolean spu_elf_build_stubs (struct bfd_link_info *, int,

View File

@ -1,3 +1,7 @@
2007-04-30 Alan Modra <amodra@bigpond.net.au>
* bfdlink.h (struct bfd_link_info): Add "info" and "minfo".
2007-04-25 Mark Mitchell <mark@codesourcery.com>
* demangle.h: Change license to LGPL + exception.

View File

@ -1,6 +1,6 @@
/* bfdlink.h -- header file for BFD link routines
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
2003, 2004, 2005 Free Software Foundation, Inc.
2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -455,8 +455,8 @@ struct bfd_link_info
struct bfd_elf_dynamic_list *dynamic_list;
};
/* This structures holds a set of callback functions. These are
called by the BFD linker routines. Except for einfo, the first
/* This structures holds a set of callback functions. These are called
by the BFD linker routines. Except for the info functions, the first
argument to each callback function is the bfd_link_info structure
being used and each function returns a boolean value. If the
function returns FALSE, then the BFD function which called it should
@ -568,9 +568,15 @@ struct bfd_link_callbacks
bfd_boolean (*notice)
(struct bfd_link_info *, const char *name,
bfd *abfd, asection *section, bfd_vma address);
/* General link info message. */
/* Error or warning link info message. */
void (*einfo)
(const char *fmt, ...);
/* General link info message. */
void (*info)
(const char *fmt, ...);
/* Message to be printed in linker map file. */
void (*minfo)
(const char *fmt, ...);
/* This callback provides a chance for users of the BFD library to
override its decision about whether to place two adjacent sections
into the same segment. */

View File

@ -1,3 +1,17 @@
2007-04-30 Alan Modra <amodra@bigpond.net.au>
* ldmain.c (link_callbacks): Init info and minfo fields.
* ldmisc.c (minfo): Do nothing if no map file.
* emultempl/spuelf.em (stack_analysis, emit_stack_syms): New vars.
(spu_after_open): Adjust spu_elf_create_sections call.
(spu_before_allocation): Likewise for spu_elf_size_stubs.
(OPTION_SPU_STACK_ANALYSIS, OPTION_SPU_STACK_SYMS): Define.
(PARSE_AND_LIST_LONGOPTS): Add new entries.
(PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Likewise.
* gen-doc.texi: Add @set for SPU and other missing targets.
* ld.texinfo: Update man page selection to match gen-doc.texi.
Document SPU features.
2007-04-28 Alan Modra <amodra@bigpond.net.au>
* ldcref.c (struct cref_hash_entry): Make "demangled" const.

View File

@ -34,6 +34,12 @@ static int non_overlay_stubs = 0;
/* Whether to emit symbols for stubs. */
static int emit_stub_syms = 0;
/* Non-zero to perform stack space analysis. */
static int stack_analysis = 0;
/* Whether to emit symbols with stack requirements for each function. */
static int emit_stack_syms = 0;
/* Range of valid addresses for loadable sections. */
static bfd_vma local_store_lo = 0;
static bfd_vma local_store_hi = 0x3ffff;
@ -70,7 +76,8 @@ spu_after_open (void)
if (is_spu_target ()
&& !link_info.relocatable
&& link_info.input_bfds != NULL
&& !spu_elf_create_sections (output_bfd, &link_info))
&& !spu_elf_create_sections (output_bfd, &link_info,
stack_analysis, emit_stack_syms))
einfo ("%X%P: can not create note section: %E\n");
gld${EMULATION_NAME}_after_open ();
@ -187,7 +194,7 @@ spu_before_allocation (void)
asection *stub, *ovtab;
if (!spu_elf_size_stubs (output_bfd, &link_info, non_overlay_stubs,
&stub, &ovtab, &toe))
stack_analysis, &stub, &ovtab, &toe))
einfo ("%X%P: can not size overlay stubs: %E\n");
if (stub != NULL)
@ -396,6 +403,8 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_SPU_STUB_SYMS (OPTION_SPU_NO_OVERLAYS + 1)
#define OPTION_SPU_NON_OVERLAY_STUBS (OPTION_SPU_STUB_SYMS + 1)
#define OPTION_SPU_LOCAL_STORE (OPTION_SPU_NON_OVERLAY_STUBS + 1)
#define OPTION_SPU_STACK_ANALYSIS (OPTION_SPU_LOCAL_STORE + 1)
#define OPTION_SPU_STACK_SYMS (OPTION_SPU_STACK_ANALYSIS + 1)
'
PARSE_AND_LIST_LONGOPTS='
@ -404,6 +413,8 @@ PARSE_AND_LIST_LONGOPTS='
{ "emit-stub-syms", no_argument, NULL, OPTION_SPU_STUB_SYMS },
{ "extra-overlay-stubs", no_argument, NULL, OPTION_SPU_NON_OVERLAY_STUBS },
{ "local-store", required_argument, NULL, OPTION_SPU_LOCAL_STORE },
{ "stack-analysis", no_argument, NULL, OPTION_SPU_STACK_ANALYSIS },
{ "emit-stack-syms", no_argument, NULL, OPTION_SPU_STACK_SYMS },
'
PARSE_AND_LIST_OPTIONS='
@ -412,7 +423,9 @@ PARSE_AND_LIST_OPTIONS='
--no-overlays No overlay handling.\n\
--emit-stub-syms Add symbols on overlay call stubs.\n\
--extra-overlay-stubs Add stubs on all calls out of overlay regions.\n\
--local-store=lo:hi Valid address range.\n"
--local-store=lo:hi Valid address range.\n\
--stack-analysis Estimate maximum stack requirement.\n\
--emit-stack-syms Add __stack_func giving stack needed for each func.\n"
));
'
@ -446,6 +459,14 @@ PARSE_AND_LIST_ARGS_CASES='
einfo (_("%P%F: invalid --local-store address range `%s'\''\n"), optarg);
}
break;
case OPTION_SPU_STACK_ANALYSIS:
stack_analysis = 1;
break;
case OPTION_SPU_STACK_SYMS:
emit_stack_syms = 1;
break;
'
LDEMUL_AFTER_OPEN=spu_after_open

View File

@ -3,14 +3,17 @@
@set GENERIC
@c 2. Specific target machines
@set H8300
@set I960
@set ARM
@set H8300
@set HPPA
@set I960
@set M68HC11
@set MMIX
@set MSP430
@set POWERPC
@set POWERPC64
@set Renesas
@set SPU
@set TICOFF
@set WIN32
@set XTENSA

View File

@ -20,33 +20,18 @@
@c Configure for the generation of man pages
@set UsesEnvVars
@set GENERIC
@set ARC
@set ARM
@set D10V
@set D30V
@set H8/300
@set H8/500
@set H8300
@set HPPA
@set I370
@set I80386
@set I860
@set I960
@set M32R
@set M68HC11
@set M680X0
@set MCORE
@set MIPS
@set MMIX
@set MSP430
@set PDP11
@set PJ
@set POWERPC
@set POWERPC64
@set SH
@set SPARC
@set TIC54X
@set V850
@set VAX
@set Renesas
@set SPU
@set TICOFF
@set WIN32
@set XTENSA
@end ifset
@ -175,6 +160,9 @@ section entitled ``GNU Free Documentation License''.
@ifset POWERPC64
* PowerPC64 ELF64:: ld and PowerPC64 64-bit ELF Support
@end ifset
@ifset SPU
* SPU ELF:: ld and SPU ELF Support
@end ifset
@ifset TICOFF
* TI COFF:: ld and the TI COFF
@end ifset
@ -5235,6 +5223,9 @@ functionality are not listed.
@ifset POWERPC64
* PowerPC64 ELF64:: @command{ld} and PowerPC64 64-bit ELF Support
@end ifset
@ifset SPU
* SPU ELF:: @command{ld} and SPU ELF Support
@end ifset
@ifset TICOFF
* TI COFF:: @command{ld} and TI COFF
@end ifset
@ -5849,6 +5840,87 @@ Use this option to turn off this feature.
@end ifclear
@end ifset
@ifset SPU
@ifclear GENERIC
@raisesections
@end ifclear
@node SPU ELF
@section @command{ld} and SPU ELF Support
@cindex SPU ELF options
@table @option
@cindex SPU plugins
@kindex --plugin
@item --plugin
This option marks an executable as a PIC plugin module.
@cindex SPU overlays
@kindex --no-overlays
@item --no-overlays
Normally, @command{ld} recognizes calls to functions within overlay
regions, and redirects such calls to an overlay manager via a stub.
@command{ld} also provides a built-in overlay manager. This option
turns off all this special overlay handling.
@cindex SPU overlay stub symbols
@kindex --emit-stub-syms
@item --emit-stub-syms
This option causes @command{ld} to label overlay stubs with a local
symbol that encodes the stub type and destination.
@cindex SPU extra overlay stubs
@kindex --extra-overlay-stubs
@item --extra-overlay-stubs
This option causes @command{ld} to add overlay call stubs on all
function calls out of overlay regions. Normally stubs are not added
on calls to non-overlay regions.
@cindex SPU local store size
@kindex --local-store=lo:hi
@item --local-store=lo:hi
@command{ld} usually checks that a final executable for SPU fits in
the address range 0 to 256k. This option may be used to change the
range. Disable the check entirely with @option{--local-store=0:0}.
@cindex SPU
@kindex --stack-analysis
@item --stack-analysis
SPU local store space is limited. Over-allocation of stack space
unnecessarily limits space available for code and data, while
under-allocation results in runtime failures. If given this option,
@command{ld} will provide an estimate of maximum stack usage.
@command{ld} does this by examining symbols in code sections to
determine the extents of functions, and looking at function prologues
for stack adjusting instructions. A call-graph is created by looking
for relocations on branch instructions. The graph is then searched
for the maximum stack usage path. Note that this analysis does not
find calls made via function pointers, and does not handle recursion
and other cycles in the call graph. Stack usage may be
under-estimated if your code makes such calls. Also, stack usage for
dynamic allocation, e.g. alloca, will not be detected. If a link map
is requested, detailed information about each function's stack usage
and calls will be given.
@cindex SPU
@kindex --emit-stack-syms
@item --emit-stack-syms
This option, if given along with @option{--stack-analysis} will result
in @command{ld} emitting stack sizing symbols for each function.
These take the form @code{__stack_<function_name>} for global
functions, and @code{__stack_<number>_<function_name>} for static
functions. @code{<number>} is the section id in hex. The value of
such symbols is the stack requirement for the corresponding function.
The symbol size will be zero, type @code{STT_NOTYPE}, binding
@code{STB_LOCAL}, and section @code{SHN_ABS}.
@end table
@ifclear GENERIC
@lowersections
@end ifclear
@end ifset
@ifset TICOFF
@ifclear GENERIC
@raisesections

View File

@ -161,6 +161,8 @@ static struct bfd_link_callbacks link_callbacks =
unattached_reloc,
notice,
einfo,
info_msg,
minfo,
ldlang_override_segment_assignment
};

View File

@ -477,11 +477,14 @@ info_assert (const char *file, unsigned int line)
void
minfo (const char *fmt, ...)
{
va_list arg;
if (config.map_file != NULL)
{
va_list arg;
va_start (arg, fmt);
vfinfo (config.map_file, fmt, arg, FALSE);
va_end (arg);
va_start (arg, fmt);
vfinfo (config.map_file, fmt, arg, FALSE);
va_end (arg);
}
}
void