2006-05-24 09:36:12 +02:00
|
|
|
# This shell script emits a C file. -*- C -*-
|
2015-01-01 15:15:26 +01:00
|
|
|
# Copyright (C) 2006-2015 Free Software Foundation, Inc.
|
2006-05-24 09:36:12 +02:00
|
|
|
#
|
2007-07-06 16:09:45 +02:00
|
|
|
# This file is part of the GNU Binutils.
|
2006-05-24 09:36:12 +02:00
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
2007-07-06 16:09:45 +02:00
|
|
|
# the Free Software Foundation; either version 3 of the License, or
|
2006-05-24 09:36:12 +02:00
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program 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.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
2007-07-06 16:09:45 +02:00
|
|
|
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
|
|
|
# MA 02110-1301, USA.
|
2006-05-24 09:36:12 +02:00
|
|
|
|
2007-07-06 16:09:45 +02:00
|
|
|
|
|
|
|
# This file is sourced from elf32.em, and defines extra avr-elf specific
|
|
|
|
# routines. It is used to generate the trampolines for the avr6 family
|
|
|
|
# of devices where one needs to address the issue that it is not possible
|
2006-05-24 09:36:12 +02:00
|
|
|
# to reach the whole program memory by using 16 bit pointers.
|
|
|
|
|
2007-07-19 21:56:10 +02:00
|
|
|
fragment <<EOF
|
2006-05-24 09:36:12 +02:00
|
|
|
|
|
|
|
#include "elf32-avr.h"
|
|
|
|
#include "ldctor.h"
|
AVR/ld: Propagate link-relax elf header flag correctly.
The AVR target has an elf header flag to indicate if an object was
assembler ready for linker relaxation. If a partial link is performed
then it is important that the link-relax flag in the output object is
set correctly, otherwise, during the final link, we might try to perform
linker relaxation on code that was not assembled suitably.
As the link-relax elf header covers the entire object file we must be
conservative when setting the flag in the output object, so, for a
partial link, any input object that does not have the link-relax flag
set will cause the output object to also not have the link-relax flag
set.
This conservative approach could be softened in future, we only need to
disable the link relax flag if an input file is not marked link-relax
ready, and the input file contains a relaxable section. However, I've
left this optimisation for a later day.
For the final link I've overloaded the use of the link-relax elf header
flag, in a final executable, the flag now indicates if the executable
was built with linker relaxation on or not.
ld/ChangeLog:
* emultempl/avrelf.em: Add include of elf/avr.h.
(avr_finish): New function.
(LDEMUL_FINISH): Added.
ld/testsuite/ChangeLog:
* ld-avr/relax-elf-flags-01.d: New file.
* ld-avr/relax-elf-flags-02.d: New file.
* ld-avr/relax-elf-flags-03.d: New file.
* ld-avr/relax-elf-flags-04.d: New file.
* ld-avr/relax-elf-flags-05.d: New file.
* ld-avr/relax-elf-flags-06.d: New file.
* ld-avr/relax-elf-flags-07.d: New file.
* ld-avr/relax-elf-flags-08.d: New file.
* ld-avr/relax-elf-flags-a.s: New file.
* ld-avr/relax-elf-flags-b.s: New file.
2014-11-23 00:25:17 +01:00
|
|
|
#include "elf/avr.h"
|
2006-05-24 09:36:12 +02:00
|
|
|
|
2007-07-19 21:56:10 +02:00
|
|
|
/* The fake file and it's corresponding section meant to hold
|
2006-05-24 09:36:12 +02:00
|
|
|
the linker stubs if needed. */
|
|
|
|
|
|
|
|
static lang_input_statement_type *stub_file;
|
|
|
|
static asection *avr_stub_section;
|
|
|
|
|
|
|
|
/* Variables set by the command-line parameters and transfered
|
|
|
|
to the bfd without use of global shared variables. */
|
|
|
|
|
|
|
|
static bfd_boolean avr_no_stubs = FALSE;
|
|
|
|
static bfd_boolean avr_debug_relax = FALSE;
|
|
|
|
static bfd_boolean avr_debug_stubs = FALSE;
|
|
|
|
static bfd_boolean avr_replace_call_ret_sequences = TRUE;
|
|
|
|
static bfd_vma avr_pc_wrap_around = 0x10000000;
|
|
|
|
|
|
|
|
/* Transfers information to the bfd frontend. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
avr_elf_set_global_bfd_parameters (void)
|
|
|
|
{
|
|
|
|
elf32_avr_setup_params (& link_info,
|
|
|
|
stub_file->the_bfd,
|
|
|
|
avr_stub_section,
|
|
|
|
avr_no_stubs,
|
|
|
|
avr_debug_stubs,
|
|
|
|
avr_debug_relax,
|
|
|
|
avr_pc_wrap_around,
|
|
|
|
avr_replace_call_ret_sequences);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Makes a conservative estimate of the trampoline section size that could
|
|
|
|
be corrected later on. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
avr_elf_${EMULATION_NAME}_before_allocation (void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
gld${EMULATION_NAME}_before_allocation ();
|
|
|
|
|
2011-03-22 19:10:48 +01:00
|
|
|
/* We only need stubs for avr6, avrxmega6, and avrxmega7. */
|
2013-01-10 21:08:03 +01:00
|
|
|
if (strcmp ("${EMULATION_NAME}","avr6")
|
2011-03-22 19:10:48 +01:00
|
|
|
&& strcmp ("${EMULATION_NAME}","avrxmega6")
|
|
|
|
&& strcmp ("${EMULATION_NAME}","avrxmega7") )
|
2006-05-24 09:36:12 +02:00
|
|
|
avr_no_stubs = TRUE;
|
|
|
|
|
|
|
|
avr_elf_set_global_bfd_parameters ();
|
|
|
|
|
|
|
|
/* If generating a relocatable output file, then
|
|
|
|
we don't have to generate the trampolines. */
|
|
|
|
if (link_info.relocatable)
|
|
|
|
avr_no_stubs = TRUE;
|
|
|
|
|
|
|
|
if (avr_no_stubs)
|
|
|
|
return;
|
|
|
|
|
2008-02-15 04:35:53 +01:00
|
|
|
ret = elf32_avr_setup_section_lists (link_info.output_bfd, &link_info);
|
2006-05-24 09:36:12 +02:00
|
|
|
|
|
|
|
if (ret < 0)
|
|
|
|
einfo ("%X%P: can not setup the input section list: %E\n");
|
|
|
|
|
|
|
|
if (ret <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Call into the BFD backend to do the real "stub"-work. */
|
2008-02-15 04:35:53 +01:00
|
|
|
if (! elf32_avr_size_stubs (link_info.output_bfd, &link_info, TRUE))
|
2006-05-24 09:36:12 +02:00
|
|
|
einfo ("%X%P: can not size stub section: %E\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This is called before the input files are opened. We create a new
|
|
|
|
fake input file to hold the stub section and generate the section itself. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
avr_elf_create_output_section_statements (void)
|
|
|
|
{
|
|
|
|
flagword flags;
|
|
|
|
|
|
|
|
stub_file = lang_add_input_file ("linker stubs",
|
|
|
|
lang_input_file_is_fake_enum,
|
|
|
|
NULL);
|
|
|
|
|
2008-02-15 04:35:53 +01:00
|
|
|
stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
|
2006-05-24 09:36:12 +02:00
|
|
|
if (stub_file->the_bfd == NULL
|
|
|
|
|| !bfd_set_arch_mach (stub_file->the_bfd,
|
2008-02-15 04:35:53 +01:00
|
|
|
bfd_get_arch (link_info.output_bfd),
|
|
|
|
bfd_get_mach (link_info.output_bfd)))
|
2006-05-24 09:36:12 +02:00
|
|
|
{
|
|
|
|
einfo ("%X%P: can not create stub BFD %E\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now we add the stub section. */
|
|
|
|
|
|
|
|
flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
|
|
|
|
| SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
|
2008-07-07 02:46:51 +02:00
|
|
|
avr_stub_section = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
|
|
|
|
".trampolines",
|
|
|
|
flags);
|
|
|
|
if (avr_stub_section == NULL)
|
2006-05-24 09:36:12 +02:00
|
|
|
goto err_ret;
|
|
|
|
|
|
|
|
avr_stub_section->alignment_power = 1;
|
2007-07-19 21:56:10 +02:00
|
|
|
|
2006-05-24 09:36:12 +02:00
|
|
|
ldlang_add_file (stub_file);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
err_ret:
|
|
|
|
einfo ("%X%P: can not make stub section: %E\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Re-calculates the size of the stubs so that we won't waste space. */
|
|
|
|
|
|
|
|
static void
|
2009-08-10 09:50:56 +02:00
|
|
|
avr_elf_after_allocation (void)
|
2007-07-19 21:56:10 +02:00
|
|
|
{
|
2009-11-26 14:45:25 +01:00
|
|
|
if (!avr_no_stubs && ! RELAXATION_ENABLED)
|
2006-05-24 09:36:12 +02:00
|
|
|
{
|
2009-08-10 09:50:56 +02:00
|
|
|
/* If relaxing, elf32_avr_size_stubs will be called from
|
|
|
|
elf32_avr_relax_section. */
|
2012-07-25 00:23:21 +02:00
|
|
|
if (!elf32_avr_size_stubs (link_info.output_bfd, &link_info, TRUE))
|
2009-08-10 09:50:56 +02:00
|
|
|
einfo ("%X%P: can not size stub section: %E\n");
|
2006-05-24 09:36:12 +02:00
|
|
|
}
|
|
|
|
|
2009-08-10 09:50:56 +02:00
|
|
|
gld${EMULATION_NAME}_after_allocation ();
|
|
|
|
|
|
|
|
/* Now build the linker stubs. */
|
|
|
|
if (!avr_no_stubs)
|
|
|
|
{
|
|
|
|
if (!elf32_avr_build_stubs (&link_info))
|
|
|
|
einfo ("%X%P: can not build stubs: %E\n");
|
|
|
|
}
|
2006-05-24 09:36:12 +02:00
|
|
|
}
|
|
|
|
|
2013-02-05 23:38:34 +01:00
|
|
|
static void
|
|
|
|
avr_elf_before_parse (void)
|
|
|
|
{
|
|
|
|
/* Don't create a demand-paged executable, since this feature isn't
|
|
|
|
meaningful in AVR. */
|
|
|
|
config.magic_demand_paged = FALSE;
|
|
|
|
|
|
|
|
gld${EMULATION_NAME}_before_parse ();
|
|
|
|
}
|
2006-05-24 09:36:12 +02:00
|
|
|
|
AVR/ld: Propagate link-relax elf header flag correctly.
The AVR target has an elf header flag to indicate if an object was
assembler ready for linker relaxation. If a partial link is performed
then it is important that the link-relax flag in the output object is
set correctly, otherwise, during the final link, we might try to perform
linker relaxation on code that was not assembled suitably.
As the link-relax elf header covers the entire object file we must be
conservative when setting the flag in the output object, so, for a
partial link, any input object that does not have the link-relax flag
set will cause the output object to also not have the link-relax flag
set.
This conservative approach could be softened in future, we only need to
disable the link relax flag if an input file is not marked link-relax
ready, and the input file contains a relaxable section. However, I've
left this optimisation for a later day.
For the final link I've overloaded the use of the link-relax elf header
flag, in a final executable, the flag now indicates if the executable
was built with linker relaxation on or not.
ld/ChangeLog:
* emultempl/avrelf.em: Add include of elf/avr.h.
(avr_finish): New function.
(LDEMUL_FINISH): Added.
ld/testsuite/ChangeLog:
* ld-avr/relax-elf-flags-01.d: New file.
* ld-avr/relax-elf-flags-02.d: New file.
* ld-avr/relax-elf-flags-03.d: New file.
* ld-avr/relax-elf-flags-04.d: New file.
* ld-avr/relax-elf-flags-05.d: New file.
* ld-avr/relax-elf-flags-06.d: New file.
* ld-avr/relax-elf-flags-07.d: New file.
* ld-avr/relax-elf-flags-08.d: New file.
* ld-avr/relax-elf-flags-a.s: New file.
* ld-avr/relax-elf-flags-b.s: New file.
2014-11-23 00:25:17 +01:00
|
|
|
static void
|
|
|
|
avr_finish (void)
|
|
|
|
{
|
|
|
|
bfd *abfd;
|
|
|
|
bfd_boolean avr_link_relax;
|
|
|
|
|
|
|
|
if (link_info.relocatable)
|
|
|
|
{
|
|
|
|
avr_link_relax = TRUE;
|
|
|
|
for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
|
|
|
|
{
|
|
|
|
/* Don't let the linker stubs prevent the final object being
|
|
|
|
marked as link-relax ready. */
|
|
|
|
if ((elf_elfheader (abfd)->e_flags
|
|
|
|
& EF_AVR_LINKRELAX_PREPARED) == 0
|
|
|
|
&& abfd != stub_file->the_bfd)
|
|
|
|
{
|
|
|
|
avr_link_relax = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
avr_link_relax = RELAXATION_ENABLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
abfd = link_info.output_bfd;
|
|
|
|
if (avr_link_relax)
|
|
|
|
elf_elfheader (abfd)->e_flags |= EF_AVR_LINKRELAX_PREPARED;
|
|
|
|
else
|
|
|
|
elf_elfheader (abfd)->e_flags &= ~EF_AVR_LINKRELAX_PREPARED;
|
|
|
|
|
|
|
|
finish_default ();
|
|
|
|
}
|
2006-05-24 09:36:12 +02:00
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
|
|
PARSE_AND_LIST_PROLOGUE='
|
|
|
|
|
|
|
|
#define OPTION_NO_CALL_RET_REPLACEMENT 301
|
|
|
|
#define OPTION_PMEM_WRAP_AROUND 302
|
|
|
|
#define OPTION_NO_STUBS 303
|
|
|
|
#define OPTION_DEBUG_STUBS 304
|
|
|
|
#define OPTION_DEBUG_RELAX 305
|
|
|
|
'
|
|
|
|
|
|
|
|
PARSE_AND_LIST_LONGOPTS='
|
2007-07-19 21:56:10 +02:00
|
|
|
{ "no-call-ret-replacement", no_argument,
|
2006-05-24 09:36:12 +02:00
|
|
|
NULL, OPTION_NO_CALL_RET_REPLACEMENT},
|
2007-07-19 21:56:10 +02:00
|
|
|
{ "pmem-wrap-around", required_argument,
|
2006-05-24 09:36:12 +02:00
|
|
|
NULL, OPTION_PMEM_WRAP_AROUND},
|
2007-07-19 21:56:10 +02:00
|
|
|
{ "no-stubs", no_argument,
|
2006-05-24 09:36:12 +02:00
|
|
|
NULL, OPTION_NO_STUBS},
|
2007-07-19 21:56:10 +02:00
|
|
|
{ "debug-stubs", no_argument,
|
2006-05-24 09:36:12 +02:00
|
|
|
NULL, OPTION_DEBUG_STUBS},
|
2007-07-19 21:56:10 +02:00
|
|
|
{ "debug-relax", no_argument,
|
2006-05-24 09:36:12 +02:00
|
|
|
NULL, OPTION_DEBUG_RELAX},
|
|
|
|
'
|
|
|
|
|
|
|
|
PARSE_AND_LIST_OPTIONS='
|
2007-08-17 15:50:48 +02:00
|
|
|
fprintf (file, _(" --pmem-wrap-around=<val> "
|
|
|
|
"Make the linker relaxation machine assume that a\n"
|
|
|
|
" "
|
|
|
|
" program counter wrap-around occures at address\n"
|
|
|
|
" "
|
|
|
|
" <val>. Supported values: 8k, 16k, 32k and 64k.\n"));
|
|
|
|
fprintf (file, _(" --no-call-ret-replacement "
|
|
|
|
"The relaxation machine normally will\n"
|
|
|
|
" "
|
|
|
|
" substitute two immediately following call/ret\n"
|
|
|
|
" "
|
|
|
|
" instructions by a single jump instruction.\n"
|
|
|
|
" "
|
|
|
|
" This option disables this optimization.\n"));
|
|
|
|
fprintf (file, _(" --no-stubs "
|
|
|
|
"If the linker detects to attempt to access\n"
|
|
|
|
" "
|
|
|
|
" an instruction beyond 128k by a reloc that\n"
|
|
|
|
" "
|
|
|
|
" is limited to 128k max, it inserts a jump\n"
|
|
|
|
" "
|
|
|
|
" stub. You can de-active this with this switch.\n"));
|
|
|
|
fprintf (file, _(" --debug-stubs "
|
|
|
|
"Used for debugging avr-ld.\n"));
|
|
|
|
fprintf (file, _(" --debug-relax "
|
|
|
|
"Used for debugging avr-ld.\n"));
|
2006-05-24 09:36:12 +02:00
|
|
|
'
|
|
|
|
|
|
|
|
PARSE_AND_LIST_ARGS_CASES='
|
|
|
|
|
|
|
|
case OPTION_PMEM_WRAP_AROUND:
|
2007-07-19 21:56:10 +02:00
|
|
|
{
|
2006-05-24 09:36:12 +02:00
|
|
|
/* This variable is defined in the bfd library. */
|
|
|
|
if ((!strcmp (optarg,"32k")) || (!strcmp (optarg,"32K")))
|
|
|
|
avr_pc_wrap_around = 32768;
|
2007-05-05 08:51:24 +02:00
|
|
|
else if ((!strcmp (optarg,"8k")) || (!strcmp (optarg,"8K")))
|
|
|
|
avr_pc_wrap_around = 8192;
|
2006-05-24 09:36:12 +02:00
|
|
|
else if ((!strcmp (optarg,"16k")) || (!strcmp (optarg,"16K")))
|
|
|
|
avr_pc_wrap_around = 16384;
|
|
|
|
else if ((!strcmp (optarg,"64k")) || (!strcmp (optarg,"64K")))
|
|
|
|
avr_pc_wrap_around = 0x10000;
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPTION_DEBUG_STUBS:
|
|
|
|
avr_debug_stubs = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPTION_DEBUG_RELAX:
|
|
|
|
avr_debug_relax = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPTION_NO_STUBS:
|
|
|
|
avr_no_stubs = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OPTION_NO_CALL_RET_REPLACEMENT:
|
|
|
|
{
|
|
|
|
/* This variable is defined in the bfd library. */
|
|
|
|
avr_replace_call_ret_sequences = FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
'
|
|
|
|
|
|
|
|
#
|
|
|
|
# Put these extra avr-elf routines in ld_${EMULATION_NAME}_emulation
|
|
|
|
#
|
2013-02-05 23:38:34 +01:00
|
|
|
LDEMUL_BEFORE_PARSE=avr_elf_before_parse
|
2006-05-24 09:36:12 +02:00
|
|
|
LDEMUL_BEFORE_ALLOCATION=avr_elf_${EMULATION_NAME}_before_allocation
|
2009-08-10 09:50:56 +02:00
|
|
|
LDEMUL_AFTER_ALLOCATION=avr_elf_after_allocation
|
2006-05-24 09:36:12 +02:00
|
|
|
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=avr_elf_create_output_section_statements
|
AVR/ld: Propagate link-relax elf header flag correctly.
The AVR target has an elf header flag to indicate if an object was
assembler ready for linker relaxation. If a partial link is performed
then it is important that the link-relax flag in the output object is
set correctly, otherwise, during the final link, we might try to perform
linker relaxation on code that was not assembled suitably.
As the link-relax elf header covers the entire object file we must be
conservative when setting the flag in the output object, so, for a
partial link, any input object that does not have the link-relax flag
set will cause the output object to also not have the link-relax flag
set.
This conservative approach could be softened in future, we only need to
disable the link relax flag if an input file is not marked link-relax
ready, and the input file contains a relaxable section. However, I've
left this optimisation for a later day.
For the final link I've overloaded the use of the link-relax elf header
flag, in a final executable, the flag now indicates if the executable
was built with linker relaxation on or not.
ld/ChangeLog:
* emultempl/avrelf.em: Add include of elf/avr.h.
(avr_finish): New function.
(LDEMUL_FINISH): Added.
ld/testsuite/ChangeLog:
* ld-avr/relax-elf-flags-01.d: New file.
* ld-avr/relax-elf-flags-02.d: New file.
* ld-avr/relax-elf-flags-03.d: New file.
* ld-avr/relax-elf-flags-04.d: New file.
* ld-avr/relax-elf-flags-05.d: New file.
* ld-avr/relax-elf-flags-06.d: New file.
* ld-avr/relax-elf-flags-07.d: New file.
* ld-avr/relax-elf-flags-08.d: New file.
* ld-avr/relax-elf-flags-a.s: New file.
* ld-avr/relax-elf-flags-b.s: New file.
2014-11-23 00:25:17 +01:00
|
|
|
LDEMUL_FINISH=avr_finish
|