2698 lines
104 KiB
C
2698 lines
104 KiB
C
/* This file is is generated by a shell script. DO NOT EDIT! */
|
|
|
|
/* 32 bit ELF emulation code for elf32briscv
|
|
Copyright (C) 1991-2022 Free Software Foundation, Inc.
|
|
Written by Steve Chamberlain <sac@cygnus.com>
|
|
ELF support by Ian Lance Taylor <ian@cygnus.com>
|
|
|
|
This file is part of the GNU Binutils.
|
|
|
|
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
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(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
|
|
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
|
MA 02110-1301, USA. */
|
|
|
|
#define TARGET_IS_elf32briscv
|
|
|
|
#include "sysdep.h"
|
|
#include "bfd.h"
|
|
#include "libiberty.h"
|
|
#include "getopt.h"
|
|
#include "bfdlink.h"
|
|
#include "ctf-api.h"
|
|
#include "ld.h"
|
|
#include "ldmain.h"
|
|
#include "ldmisc.h"
|
|
#include "ldexp.h"
|
|
#include "ldlang.h"
|
|
#include "ldfile.h"
|
|
#include "ldemul.h"
|
|
#include <ldgram.h>
|
|
#include "elf-bfd.h"
|
|
#include "ldelf.h"
|
|
#include "ldelfgen.h"
|
|
|
|
/* Declare functions used by various EXTRA_EM_FILEs. */
|
|
static void gldelf32briscv_before_parse (void);
|
|
static void gldelf32briscv_before_plugin_all_symbols_read
|
|
(void);
|
|
static void gldelf32briscv_after_open (void);
|
|
static void gldelf32briscv_before_allocation (void);
|
|
static void gldelf32briscv_after_allocation (void);
|
|
|
|
|
|
#include "ldmain.h"
|
|
#include "ldctor.h"
|
|
#include "elf/riscv.h"
|
|
#include "elfxx-riscv.h"
|
|
|
|
static void
|
|
riscv_elf_before_allocation (void)
|
|
{
|
|
gldelf32briscv_before_allocation ();
|
|
|
|
if (link_info.discard == discard_sec_merge)
|
|
link_info.discard = discard_l;
|
|
|
|
if (!bfd_link_relocatable (&link_info))
|
|
{
|
|
/* We always need at least some relaxation to handle code alignment. */
|
|
if (RELAXATION_DISABLED_BY_USER)
|
|
TARGET_ENABLE_RELAXATION;
|
|
else
|
|
ENABLE_RELAXATION;
|
|
}
|
|
|
|
link_info.relax_pass = 3;
|
|
}
|
|
|
|
static void
|
|
gldelf32briscv_after_allocation (void)
|
|
{
|
|
int need_layout = 0;
|
|
|
|
/* Don't attempt to discard unused .eh_frame sections until the final link,
|
|
as we can't reliably tell if they're used until after relaxation. */
|
|
if (!bfd_link_relocatable (&link_info))
|
|
{
|
|
need_layout = bfd_elf_discard_info (link_info.output_bfd, &link_info);
|
|
if (need_layout < 0)
|
|
{
|
|
einfo (_("%X%P: .eh_frame/.stab edit: %E\n"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* PR 27566, if the phase of data segment is exp_seg_relro_adjust,
|
|
that means we are still adjusting the relro, and shouldn't do the
|
|
relaxations at this stage. Otherwise, we will get the symbol
|
|
values beofore handling the relro, and may cause truncated fails
|
|
when the relax range crossing the data segment. One of the solution
|
|
is to monitor the data segment phase while relaxing, to know whether
|
|
the relro has been handled or not.
|
|
|
|
I think we probably need to record more information about data
|
|
segment or alignments in the future, to make sure it is safe
|
|
to doing relaxations. */
|
|
enum phase_enum *phase = &(expld.dataseg.phase);
|
|
bfd_elf32_riscv_set_data_segment_info (&link_info, (int *) phase);
|
|
|
|
ldelf_map_segments (need_layout);
|
|
}
|
|
|
|
/* This is a convenient point to tell BFD about target specific flags.
|
|
After the output has been created, but before inputs are read. */
|
|
|
|
static void
|
|
riscv_create_output_section_statements (void)
|
|
{
|
|
/* See PR 22920 for an example of why this is necessary. */
|
|
if (strstr (bfd_get_target (link_info.output_bfd), "riscv") == NULL)
|
|
{
|
|
/* The RISC-V backend needs special fields in the output hash structure.
|
|
These will only be created if the output format is a RISC-V format,
|
|
hence we do not support linking and changing output formats at the
|
|
same time. Use a link followed by objcopy to change output formats. */
|
|
einfo (_("%F%P: error: cannot change output format"
|
|
" whilst linking %s binaries\n"), "RISC-V");
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
gldelf32briscv_before_parse (void)
|
|
{
|
|
ldfile_set_output_arch ("riscv", bfd_arch_riscv);
|
|
input_flags.dynamic = true;
|
|
config.has_shared = false;
|
|
config.separate_code = false;
|
|
link_info.check_relocs_after_open_input = true;
|
|
link_info.relro = DEFAULT_LD_Z_RELRO;
|
|
link_info.separate_code = DEFAULT_LD_Z_SEPARATE_CODE;
|
|
link_info.warn_execstack = DEFAULT_LD_WARN_EXECSTACK;
|
|
link_info.no_warn_rwx_segments = ! DEFAULT_LD_WARN_RWX_SEGMENTS;
|
|
link_info.default_execstack = DEFAULT_LD_EXECSTACK;
|
|
}
|
|
|
|
|
|
/* These variables are used to implement target options */
|
|
|
|
static char *audit; /* colon (typically) separated list of libs */
|
|
static char *depaudit; /* colon (typically) separated list of libs */
|
|
|
|
|
|
/* This is called before calling plugin 'all symbols read' hook. */
|
|
|
|
static void
|
|
gldelf32briscv_before_plugin_all_symbols_read (void)
|
|
{
|
|
ldelf_before_plugin_all_symbols_read (false, false,
|
|
false,
|
|
false,
|
|
32, "/opt/riscv");
|
|
}
|
|
|
|
/* This is called after all the input files have been opened. */
|
|
|
|
static void
|
|
gldelf32briscv_after_open (void)
|
|
{
|
|
ldelf_after_open (false, false,
|
|
false, false, 32, "/opt/riscv");
|
|
}
|
|
|
|
|
|
/* This is called after the sections have been attached to output
|
|
sections, but before any sizes or addresses have been set. */
|
|
|
|
static void
|
|
gldelf32briscv_before_allocation (void)
|
|
{
|
|
ldelf_before_allocation (audit, depaudit, NULL);
|
|
}
|
|
|
|
|
|
static char *
|
|
gldelf32briscv_get_script (int *isfile)
|
|
{
|
|
*isfile = 0;
|
|
|
|
if (bfd_link_relocatable (&link_info) && config.build_constructors)
|
|
return
|
|
"/* Script for -Ur */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
/* For some reason, the Solaris linker makes bad executables\n\
|
|
if gld -r is used and the intermediate file has sections starting\n\
|
|
at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld\n\
|
|
bug. But for now assigning the zero vmas works. */\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
.interp 0 : { *(.interp) }\n\
|
|
.note.gnu.build-id 0: { *(.note.gnu.build-id) }\n\
|
|
.hash 0 : { *(.hash) }\n\
|
|
.gnu.hash 0 : { *(.gnu.hash) }\n\
|
|
.dynsym 0 : { *(.dynsym) }\n\
|
|
.dynstr 0 : { *(.dynstr) }\n\
|
|
.gnu.version 0 : { *(.gnu.version) }\n\
|
|
.gnu.version_d 0: { *(.gnu.version_d) }\n\
|
|
.gnu.version_r 0: { *(.gnu.version_r) }\n\
|
|
.rela.init 0 : { *(.rela.init) }\n\
|
|
.rela.text 0 : { *(.rela.text) }\n"
|
|
" .rela.fini 0 : { *(.rela.fini) }\n\
|
|
.rela.rodata 0 : { *(.rela.rodata) }\n\
|
|
.rela.data.rel.ro 0 : { *(.rela.data.rel.ro) }\n\
|
|
.rela.data 0 : { *(.rela.data) }\n\
|
|
.rela.tdata 0 : { *(.rela.tdata) }\n\
|
|
.rela.tbss 0 : { *(.rela.tbss) }\n\
|
|
.rela.ctors 0 : { *(.rela.ctors) }\n\
|
|
.rela.dtors 0 : { *(.rela.dtors) }\n\
|
|
.rela.got 0 : { *(.rela.got) }\n\
|
|
.rela.sdata 0 : { *(.rela.sdata) }\n\
|
|
.rela.sbss 0 : { *(.rela.sbss) }\n\
|
|
.rela.sdata2 0 : { *(.rela.sdata2) }\n\
|
|
.rela.sbss2 0 : { *(.rela.sbss2) }\n\
|
|
.rela.bss 0 : { *(.rela.bss) }\n\
|
|
.rela.ifunc 0 : { *(.rela.ifunc) }\n\
|
|
.rela.plt 0 :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
}\n\
|
|
.init 0 :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.init)))\n\
|
|
}\n\
|
|
.plt 0 : { *(.plt) }\n\
|
|
.text 0 :\n"
|
|
" {\n\
|
|
*(.text .stub)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini 0 :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
.rodata 0 : { *(.rodata) }\n\
|
|
.rodata1 0 : { *(.rodata1) }\n\
|
|
.sdata2 0 :\n\
|
|
{\n\
|
|
*(.sdata2)\n\
|
|
}\n\
|
|
.sbss2 0 : { *(.sbss2) }\n\
|
|
.eh_frame_hdr 0 : { *(.eh_frame_hdr) }\n\
|
|
.eh_frame 0 : ONLY_IF_RO { KEEP (*(.eh_frame)) }\n\
|
|
.gcc_except_table 0 : ONLY_IF_RO { *(.gcc_except_table) }\n\
|
|
.gnu_extab 0 : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges 0 : ONLY_IF_RO { *(.exception_ranges) }\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame 0 : ONLY_IF_RW { KEEP (*(.eh_frame)) }\n\
|
|
.gnu_extab 0 : ONLY_IF_RW { *(.gnu_extab) }\n"
|
|
" .gcc_except_table 0 : ONLY_IF_RW { *(.gcc_except_table) }\n\
|
|
.exception_ranges 0 : ONLY_IF_RW { *(.exception_ranges) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata 0 :\n\
|
|
{\n\
|
|
*(.tdata)\n\
|
|
}\n\
|
|
.tbss 0 : { *(.tbss) }\n\
|
|
.jcr 0 : { KEEP (*(.jcr)) }\n\
|
|
.dynamic 0 : { *(.dynamic) }\n\
|
|
.data 0 :\n\
|
|
{\n\
|
|
*(.data)\n\
|
|
SORT(CONSTRUCTORS)\n\
|
|
}\n\
|
|
.data1 0 : { *(.data1) }\n\
|
|
.got 0 : { *(.got) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata 0 :\n\
|
|
{\n\
|
|
*(.sdata)\n\
|
|
}\n\
|
|
.sbss 0 :\n"
|
|
" {\n\
|
|
*(.sbss)\n\
|
|
}\n\
|
|
.bss 0 :\n\
|
|
{\n\
|
|
*(.bss)\n\
|
|
}\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
}\n\n"
|
|
; else if (bfd_link_relocatable (&link_info)) return
|
|
"/* Script for -r */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
/* For some reason, the Solaris linker makes bad executables\n\
|
|
if gld -r is used and the intermediate file has sections starting\n\
|
|
at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld\n\
|
|
bug. But for now assigning the zero vmas works. */\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
.interp 0 : { *(.interp) }\n\
|
|
.note.gnu.build-id 0: { *(.note.gnu.build-id) }\n\
|
|
.hash 0 : { *(.hash) }\n\
|
|
.gnu.hash 0 : { *(.gnu.hash) }\n\
|
|
.dynsym 0 : { *(.dynsym) }\n\
|
|
.dynstr 0 : { *(.dynstr) }\n\
|
|
.gnu.version 0 : { *(.gnu.version) }\n\
|
|
.gnu.version_d 0: { *(.gnu.version_d) }\n\
|
|
.gnu.version_r 0: { *(.gnu.version_r) }\n\
|
|
.rela.init 0 : { *(.rela.init) }\n\
|
|
.rela.text 0 : { *(.rela.text) }\n"
|
|
" .rela.fini 0 : { *(.rela.fini) }\n\
|
|
.rela.rodata 0 : { *(.rela.rodata) }\n\
|
|
.rela.data.rel.ro 0 : { *(.rela.data.rel.ro) }\n\
|
|
.rela.data 0 : { *(.rela.data) }\n\
|
|
.rela.tdata 0 : { *(.rela.tdata) }\n\
|
|
.rela.tbss 0 : { *(.rela.tbss) }\n\
|
|
.rela.ctors 0 : { *(.rela.ctors) }\n\
|
|
.rela.dtors 0 : { *(.rela.dtors) }\n\
|
|
.rela.got 0 : { *(.rela.got) }\n\
|
|
.rela.sdata 0 : { *(.rela.sdata) }\n\
|
|
.rela.sbss 0 : { *(.rela.sbss) }\n\
|
|
.rela.sdata2 0 : { *(.rela.sdata2) }\n\
|
|
.rela.sbss2 0 : { *(.rela.sbss2) }\n\
|
|
.rela.bss 0 : { *(.rela.bss) }\n\
|
|
.rela.ifunc 0 : { *(.rela.ifunc) }\n\
|
|
.rela.plt 0 :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
}\n\
|
|
.init 0 :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.init)))\n\
|
|
}\n\
|
|
.plt 0 : { *(.plt) }\n\
|
|
.text 0 :\n"
|
|
" {\n\
|
|
*(.text .stub)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini 0 :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
.rodata 0 : { *(.rodata) }\n\
|
|
.rodata1 0 : { *(.rodata1) }\n\
|
|
.sdata2 0 :\n\
|
|
{\n\
|
|
*(.sdata2)\n\
|
|
}\n\
|
|
.sbss2 0 : { *(.sbss2) }\n\
|
|
.eh_frame_hdr 0 : { *(.eh_frame_hdr) }\n\
|
|
.eh_frame 0 : ONLY_IF_RO { KEEP (*(.eh_frame)) }\n\
|
|
.gcc_except_table 0 : ONLY_IF_RO { *(.gcc_except_table) }\n\
|
|
.gnu_extab 0 : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges 0 : ONLY_IF_RO { *(.exception_ranges) }\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame 0 : ONLY_IF_RW { KEEP (*(.eh_frame)) }\n\
|
|
.gnu_extab 0 : ONLY_IF_RW { *(.gnu_extab) }\n"
|
|
" .gcc_except_table 0 : ONLY_IF_RW { *(.gcc_except_table) }\n\
|
|
.exception_ranges 0 : ONLY_IF_RW { *(.exception_ranges) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata 0 :\n\
|
|
{\n\
|
|
*(.tdata)\n\
|
|
}\n\
|
|
.tbss 0 : { *(.tbss) }\n\
|
|
.jcr 0 : { KEEP (*(.jcr)) }\n\
|
|
.dynamic 0 : { *(.dynamic) }\n\
|
|
.data 0 :\n\
|
|
{\n\
|
|
*(.data)\n\
|
|
}\n\
|
|
.data1 0 : { *(.data1) }\n\
|
|
.got 0 : { *(.got) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata 0 :\n\
|
|
{\n\
|
|
*(.sdata)\n\
|
|
}\n\
|
|
.sbss 0 :\n\
|
|
{\n"
|
|
" *(.sbss)\n\
|
|
}\n\
|
|
.bss 0 :\n\
|
|
{\n\
|
|
*(.bss)\n\
|
|
}\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
}\n\n"
|
|
; else if (!config.text_read_only) return
|
|
"/* Script for -N */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
ENTRY(_start)\n\
|
|
SEARCH_DIR(\"/opt/riscv/riscv32-unknown-elf/lib\");\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
/* Read-only sections, merged into text segment: */\n\
|
|
PROVIDE (__executable_start = SEGMENT_START(\"text-segment\", 0x10000)); . = SEGMENT_START(\"text-segment\", 0x10000) + SIZEOF_HEADERS;\n\
|
|
.interp : { *(.interp) }\n\
|
|
.note.gnu.build-id : { *(.note.gnu.build-id) }\n\
|
|
.hash : { *(.hash) }\n\
|
|
.gnu.hash : { *(.gnu.hash) }\n\
|
|
.dynsym : { *(.dynsym) }\n\
|
|
.dynstr : { *(.dynstr) }\n\
|
|
.gnu.version : { *(.gnu.version) }\n\
|
|
.gnu.version_d : { *(.gnu.version_d) }\n\
|
|
.gnu.version_r : { *(.gnu.version_r) }\n\
|
|
.rela.init : { *(.rela.init) }\n\
|
|
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }\n"
|
|
" .rela.fini : { *(.rela.fini) }\n\
|
|
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }\n\
|
|
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }\n\
|
|
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }\n\
|
|
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }\n\
|
|
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }\n\
|
|
.rela.ctors : { *(.rela.ctors) }\n\
|
|
.rela.dtors : { *(.rela.dtors) }\n\
|
|
.rela.got : { *(.rela.got) }\n\
|
|
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }\n\
|
|
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }\n\
|
|
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }\n\
|
|
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }\n\
|
|
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }\n\
|
|
.rela.ifunc : { *(.rela.ifunc) }\n\
|
|
.rela.plt :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_start = .);\n\
|
|
*(.rela.iplt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_end = .);\n\
|
|
}\n\
|
|
.init :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.init)))\n"
|
|
" }\n\
|
|
.plt : { *(.plt) *(.iplt) }\n\
|
|
.text :\n\
|
|
{\n\
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)\n\
|
|
*(.text.exit .text.exit.*)\n\
|
|
*(.text.startup .text.startup.*)\n\
|
|
*(.text.hot .text.hot.*)\n\
|
|
*(SORT(.text.sorted.*))\n\
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
PROVIDE (__etext = .);\n\
|
|
PROVIDE (_etext = .);\n\
|
|
PROVIDE (etext = .);\n\
|
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\n\
|
|
.rodata1 : { *(.rodata1) }\n\
|
|
.sdata2 :\n\
|
|
{\n\
|
|
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)\n"
|
|
" }\n\
|
|
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }\n\
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }\n\
|
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }\n\
|
|
/* Adjust the address for the data segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n\
|
|
. = .;\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }\n\
|
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__tdata_start = .);\n\
|
|
*(.tdata .tdata.* .gnu.linkonce.td.*)\n\
|
|
}\n\
|
|
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\n\
|
|
.preinit_array :\n\
|
|
{\n"
|
|
" PROVIDE_HIDDEN (__preinit_array_start = .);\n\
|
|
KEEP (*(.preinit_array))\n\
|
|
PROVIDE_HIDDEN (__preinit_array_end = .);\n\
|
|
}\n\
|
|
.init_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__init_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))\n\
|
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))\n\
|
|
PROVIDE_HIDDEN (__init_array_end = .);\n\
|
|
}\n\
|
|
.fini_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__fini_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))\n\
|
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))\n\
|
|
PROVIDE_HIDDEN (__fini_array_end = .);\n\
|
|
}\n\
|
|
.ctors :\n\
|
|
{\n\
|
|
/* gcc uses crtbegin.o to find the start of\n\
|
|
the constructors, so we make sure it is\n\
|
|
first. Because this is a wildcard, it\n\
|
|
doesn't matter if the user does not\n\
|
|
actually link against crtbegin.o; the\n\
|
|
linker won't look for a file to match a\n\
|
|
wildcard. The wildcard also means that it\n\
|
|
doesn't matter which directory crtbegin.o\n\
|
|
is in. */\n\
|
|
KEEP (*crtbegin.o(.ctors))\n\
|
|
KEEP (*crtbegin?.o(.ctors))\n\
|
|
/* We don't want to include the .ctor section from\n\
|
|
the crtend.o file until after the sorted ctors.\n\
|
|
The .ctor section from the crtend file contains the\n\
|
|
end of ctors marker and it must be last */\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\n\
|
|
KEEP (*(SORT(.ctors.*)))\n\
|
|
KEEP (*(.ctors))\n\
|
|
}\n\
|
|
.dtors :\n\
|
|
{\n\
|
|
KEEP (*crtbegin.o(.dtors))\n\
|
|
KEEP (*crtbegin?.o(.dtors))\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\n\
|
|
KEEP (*(SORT(.dtors.*)))\n\
|
|
KEEP (*(.dtors))\n\
|
|
}\n\
|
|
.jcr : { KEEP (*(.jcr)) }\n\
|
|
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }\n\
|
|
.dynamic : { *(.dynamic) }\n\
|
|
.data :\n\
|
|
{\n\
|
|
__DATA_BEGIN__ = .;\n\
|
|
*(.data .data.* .gnu.linkonce.d.*)\n\
|
|
SORT(CONSTRUCTORS)\n\
|
|
}\n\
|
|
.data1 : { *(.data1) }\n\
|
|
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata :\n\
|
|
{\n\
|
|
__SDATA_BEGIN__ = .;\n\
|
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)\n\
|
|
*(.sdata .sdata.* .gnu.linkonce.s.*)\n\
|
|
}\n\
|
|
_edata = .; PROVIDE (edata = .);\n\
|
|
. = .;\n\
|
|
__bss_start = .;\n\
|
|
.sbss :\n\
|
|
{\n\
|
|
*(.dynsbss)\n\
|
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)\n\
|
|
*(.scommon)\n\
|
|
}\n\
|
|
.bss :\n\
|
|
{\n\
|
|
*(.dynbss)\n\
|
|
*(.bss .bss.* .gnu.linkonce.b.*)\n\
|
|
*(COMMON)\n\
|
|
/* Align here to ensure that the .bss section occupies space up to\n\
|
|
_end. Align after .bss to ensure correct alignment even if the\n\
|
|
.bss section disappears because there are no input sections.\n\
|
|
FIXME: Why do we need it? When there is no .bss section, we do not\n\
|
|
pad the .data section. */\n\
|
|
. = ALIGN(. != 0 ? 32 / 8 : 1);\n\
|
|
}\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
. = SEGMENT_START(\"ldata-segment\", .);\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
__BSS_END__ = .;\n\
|
|
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,\n\
|
|
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));\n\
|
|
_end = .; PROVIDE (end = .);\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }\n\
|
|
}\n\n"
|
|
; else if (!config.magic_demand_paged) return
|
|
"/* Script for -n */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
ENTRY(_start)\n\
|
|
SEARCH_DIR(\"/opt/riscv/riscv32-unknown-elf/lib\");\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
/* Read-only sections, merged into text segment: */\n\
|
|
PROVIDE (__executable_start = SEGMENT_START(\"text-segment\", 0x10000)); . = SEGMENT_START(\"text-segment\", 0x10000) + SIZEOF_HEADERS;\n\
|
|
.interp : { *(.interp) }\n\
|
|
.note.gnu.build-id : { *(.note.gnu.build-id) }\n\
|
|
.hash : { *(.hash) }\n\
|
|
.gnu.hash : { *(.gnu.hash) }\n\
|
|
.dynsym : { *(.dynsym) }\n\
|
|
.dynstr : { *(.dynstr) }\n\
|
|
.gnu.version : { *(.gnu.version) }\n\
|
|
.gnu.version_d : { *(.gnu.version_d) }\n\
|
|
.gnu.version_r : { *(.gnu.version_r) }\n\
|
|
.rela.init : { *(.rela.init) }\n\
|
|
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }\n"
|
|
" .rela.fini : { *(.rela.fini) }\n\
|
|
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }\n\
|
|
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }\n\
|
|
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }\n\
|
|
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }\n\
|
|
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }\n\
|
|
.rela.ctors : { *(.rela.ctors) }\n\
|
|
.rela.dtors : { *(.rela.dtors) }\n\
|
|
.rela.got : { *(.rela.got) }\n\
|
|
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }\n\
|
|
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }\n\
|
|
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }\n\
|
|
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }\n\
|
|
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }\n\
|
|
.rela.ifunc : { *(.rela.ifunc) }\n\
|
|
.rela.plt :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_start = .);\n\
|
|
*(.rela.iplt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_end = .);\n\
|
|
}\n\
|
|
.init :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.init)))\n"
|
|
" }\n\
|
|
.plt : { *(.plt) *(.iplt) }\n\
|
|
.text :\n\
|
|
{\n\
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)\n\
|
|
*(.text.exit .text.exit.*)\n\
|
|
*(.text.startup .text.startup.*)\n\
|
|
*(.text.hot .text.hot.*)\n\
|
|
*(SORT(.text.sorted.*))\n\
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
PROVIDE (__etext = .);\n\
|
|
PROVIDE (_etext = .);\n\
|
|
PROVIDE (etext = .);\n\
|
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\n\
|
|
.rodata1 : { *(.rodata1) }\n\
|
|
.sdata2 :\n\
|
|
{\n\
|
|
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)\n"
|
|
" }\n\
|
|
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }\n\
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }\n\
|
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }\n\
|
|
/* Adjust the address for the data segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n\
|
|
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }\n\
|
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__tdata_start = .);\n\
|
|
*(.tdata .tdata.* .gnu.linkonce.td.*)\n\
|
|
}\n\
|
|
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\n\
|
|
.preinit_array :\n\
|
|
{\n"
|
|
" PROVIDE_HIDDEN (__preinit_array_start = .);\n\
|
|
KEEP (*(.preinit_array))\n\
|
|
PROVIDE_HIDDEN (__preinit_array_end = .);\n\
|
|
}\n\
|
|
.init_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__init_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))\n\
|
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))\n\
|
|
PROVIDE_HIDDEN (__init_array_end = .);\n\
|
|
}\n\
|
|
.fini_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__fini_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))\n\
|
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))\n\
|
|
PROVIDE_HIDDEN (__fini_array_end = .);\n\
|
|
}\n\
|
|
.ctors :\n\
|
|
{\n\
|
|
/* gcc uses crtbegin.o to find the start of\n\
|
|
the constructors, so we make sure it is\n\
|
|
first. Because this is a wildcard, it\n\
|
|
doesn't matter if the user does not\n\
|
|
actually link against crtbegin.o; the\n\
|
|
linker won't look for a file to match a\n\
|
|
wildcard. The wildcard also means that it\n\
|
|
doesn't matter which directory crtbegin.o\n\
|
|
is in. */\n\
|
|
KEEP (*crtbegin.o(.ctors))\n\
|
|
KEEP (*crtbegin?.o(.ctors))\n\
|
|
/* We don't want to include the .ctor section from\n\
|
|
the crtend.o file until after the sorted ctors.\n\
|
|
The .ctor section from the crtend file contains the\n\
|
|
end of ctors marker and it must be last */\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\n\
|
|
KEEP (*(SORT(.ctors.*)))\n\
|
|
KEEP (*(.ctors))\n\
|
|
}\n\
|
|
.dtors :\n\
|
|
{\n\
|
|
KEEP (*crtbegin.o(.dtors))\n\
|
|
KEEP (*crtbegin?.o(.dtors))\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\n\
|
|
KEEP (*(SORT(.dtors.*)))\n\
|
|
KEEP (*(.dtors))\n\
|
|
}\n\
|
|
.jcr : { KEEP (*(.jcr)) }\n\
|
|
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }\n\
|
|
.dynamic : { *(.dynamic) }\n\
|
|
. = DATA_SEGMENT_RELRO_END (0, .);\n\
|
|
.data :\n\
|
|
{\n\
|
|
__DATA_BEGIN__ = .;\n\
|
|
*(.data .data.* .gnu.linkonce.d.*)\n\
|
|
SORT(CONSTRUCTORS)\n\
|
|
}\n\
|
|
.data1 : { *(.data1) }\n\
|
|
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata :\n\
|
|
{\n\
|
|
__SDATA_BEGIN__ = .;\n\
|
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)\n\
|
|
*(.sdata .sdata.* .gnu.linkonce.s.*)\n\
|
|
}\n\
|
|
_edata = .; PROVIDE (edata = .);\n\
|
|
. = .;\n\
|
|
__bss_start = .;\n\
|
|
.sbss :\n\
|
|
{\n\
|
|
*(.dynsbss)\n\
|
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)\n\
|
|
*(.scommon)\n\
|
|
}\n\
|
|
.bss :\n\
|
|
{\n\
|
|
*(.dynbss)\n\
|
|
*(.bss .bss.* .gnu.linkonce.b.*)\n\
|
|
*(COMMON)\n\
|
|
/* Align here to ensure that the .bss section occupies space up to\n\
|
|
_end. Align after .bss to ensure correct alignment even if the\n\
|
|
.bss section disappears because there are no input sections.\n\
|
|
FIXME: Why do we need it? When there is no .bss section, we do not\n\
|
|
pad the .data section. */\n\
|
|
. = ALIGN(. != 0 ? 32 / 8 : 1);\n\
|
|
}\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
. = SEGMENT_START(\"ldata-segment\", .);\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
__BSS_END__ = .;\n\
|
|
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,\n\
|
|
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));\n\
|
|
_end = .; PROVIDE (end = .);\n\
|
|
. = DATA_SEGMENT_END (.);\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }\n\
|
|
}\n\n"
|
|
; else if (link_info.combreloc
|
|
&& link_info.separate_code
|
|
&& (link_info.flags & DF_BIND_NOW)) return
|
|
"/* Script for -z combreloc -z separate-code -z relro -z now */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
ENTRY(_start)\n\
|
|
SEARCH_DIR(\"/opt/riscv/riscv32-unknown-elf/lib\");\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
PROVIDE (__executable_start = SEGMENT_START(\"text-segment\", 0x10000)); . = SEGMENT_START(\"text-segment\", 0x10000) + SIZEOF_HEADERS;\n\
|
|
.interp : { *(.interp) }\n\
|
|
.note.gnu.build-id : { *(.note.gnu.build-id) }\n\
|
|
.hash : { *(.hash) }\n\
|
|
.gnu.hash : { *(.gnu.hash) }\n\
|
|
.dynsym : { *(.dynsym) }\n\
|
|
.dynstr : { *(.dynstr) }\n\
|
|
.gnu.version : { *(.gnu.version) }\n\
|
|
.gnu.version_d : { *(.gnu.version_d) }\n\
|
|
.gnu.version_r : { *(.gnu.version_r) }\n\
|
|
.rela.dyn :\n\
|
|
{\n\
|
|
*(.rela.init)\n"
|
|
" *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)\n\
|
|
*(.rela.fini)\n\
|
|
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)\n\
|
|
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)\n\
|
|
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)\n\
|
|
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)\n\
|
|
*(.rela.ctors)\n\
|
|
*(.rela.dtors)\n\
|
|
*(.rela.got)\n\
|
|
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)\n\
|
|
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)\n\
|
|
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)\n\
|
|
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)\n\
|
|
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)\n\
|
|
*(.rela.ifunc)\n\
|
|
}\n\
|
|
.rela.plt :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_start = .);\n\
|
|
*(.rela.iplt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_end = .);\n\
|
|
}\n\
|
|
. = ALIGN(CONSTANT (MAXPAGESIZE));\n\
|
|
.init :\n"
|
|
" {\n\
|
|
KEEP (*(SORT_NONE(.init)))\n\
|
|
}\n\
|
|
.plt : { *(.plt) *(.iplt) }\n\
|
|
.text :\n\
|
|
{\n\
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)\n\
|
|
*(.text.exit .text.exit.*)\n\
|
|
*(.text.startup .text.startup.*)\n\
|
|
*(.text.hot .text.hot.*)\n\
|
|
*(SORT(.text.sorted.*))\n\
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
PROVIDE (__etext = .);\n\
|
|
PROVIDE (_etext = .);\n\
|
|
PROVIDE (etext = .);\n\
|
|
. = ALIGN(CONSTANT (MAXPAGESIZE));\n\
|
|
/* Adjust the address for the rodata segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n"
|
|
" . = SEGMENT_START(\"rodata-segment\", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));\n\
|
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\n\
|
|
.rodata1 : { *(.rodata1) }\n\
|
|
.sdata2 :\n\
|
|
{\n\
|
|
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)\n\
|
|
}\n\
|
|
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }\n\
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }\n\
|
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }\n\
|
|
/* Adjust the address for the data segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n\
|
|
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }\n\
|
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata :\n\
|
|
{\n"
|
|
" PROVIDE_HIDDEN (__tdata_start = .);\n\
|
|
*(.tdata .tdata.* .gnu.linkonce.td.*)\n\
|
|
}\n\
|
|
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\n\
|
|
.preinit_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__preinit_array_start = .);\n\
|
|
KEEP (*(.preinit_array))\n\
|
|
PROVIDE_HIDDEN (__preinit_array_end = .);\n\
|
|
}\n\
|
|
.init_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__init_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))\n\
|
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))\n\
|
|
PROVIDE_HIDDEN (__init_array_end = .);\n\
|
|
}\n\
|
|
.fini_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__fini_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))\n\
|
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))\n\
|
|
PROVIDE_HIDDEN (__fini_array_end = .);\n\
|
|
}\n\
|
|
.ctors :\n\
|
|
{\n\
|
|
/* gcc uses crtbegin.o to find the start of\n\
|
|
the constructors, so we make sure it is\n\
|
|
first. Because this is a wildcard, it\n\
|
|
doesn't matter if the user does not\n\
|
|
actually link against crtbegin.o; the\n\
|
|
linker won't look for a file to match a\n\
|
|
wildcard. The wildcard also means that it\n\
|
|
doesn't matter which directory crtbegin.o\n\
|
|
is in. */\n\
|
|
KEEP (*crtbegin.o(.ctors))\n\
|
|
KEEP (*crtbegin?.o(.ctors))\n\
|
|
/* We don't want to include the .ctor section from\n\
|
|
the crtend.o file until after the sorted ctors.\n\
|
|
The .ctor section from the crtend file contains the\n\
|
|
end of ctors marker and it must be last */\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\n\
|
|
KEEP (*(SORT(.ctors.*)))\n\
|
|
KEEP (*(.ctors))\n\
|
|
}\n\
|
|
.dtors :\n\
|
|
{\n\
|
|
KEEP (*crtbegin.o(.dtors))\n\
|
|
KEEP (*crtbegin?.o(.dtors))\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\n\
|
|
KEEP (*(SORT(.dtors.*)))\n\
|
|
KEEP (*(.dtors))\n\
|
|
}\n\
|
|
.jcr : { KEEP (*(.jcr)) }\n\
|
|
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }\n\
|
|
.dynamic : { *(.dynamic) }\n\
|
|
. = DATA_SEGMENT_RELRO_END (0, .);\n\
|
|
.data :\n\
|
|
{\n\
|
|
__DATA_BEGIN__ = .;\n\
|
|
*(.data .data.* .gnu.linkonce.d.*)\n\
|
|
SORT(CONSTRUCTORS)\n\
|
|
}\n\
|
|
.data1 : { *(.data1) }\n\
|
|
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata :\n\
|
|
{\n\
|
|
__SDATA_BEGIN__ = .;\n\
|
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)\n\
|
|
*(.sdata .sdata.* .gnu.linkonce.s.*)\n\
|
|
}\n\
|
|
_edata = .; PROVIDE (edata = .);\n\
|
|
. = .;\n\
|
|
__bss_start = .;\n\
|
|
.sbss :\n\
|
|
{\n\
|
|
*(.dynsbss)\n\
|
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)\n\
|
|
*(.scommon)\n\
|
|
}\n\
|
|
.bss :\n\
|
|
{\n\
|
|
*(.dynbss)\n\
|
|
*(.bss .bss.* .gnu.linkonce.b.*)\n\
|
|
*(COMMON)\n\
|
|
/* Align here to ensure that the .bss section occupies space up to\n\
|
|
_end. Align after .bss to ensure correct alignment even if the\n\
|
|
.bss section disappears because there are no input sections.\n\
|
|
FIXME: Why do we need it? When there is no .bss section, we do not\n\
|
|
pad the .data section. */\n\
|
|
. = ALIGN(. != 0 ? 32 / 8 : 1);\n\
|
|
}\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
. = SEGMENT_START(\"ldata-segment\", .);\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
__BSS_END__ = .;\n\
|
|
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,\n\
|
|
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));\n\
|
|
_end = .; PROVIDE (end = .);\n\
|
|
. = DATA_SEGMENT_END (.);\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }\n\
|
|
}\n\n"
|
|
; else if (link_info.combreloc
|
|
&& link_info.relro
|
|
&& (link_info.flags & DF_BIND_NOW)) return
|
|
"/* Script for -z combreloc -z relro -z now */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
ENTRY(_start)\n\
|
|
SEARCH_DIR(\"/opt/riscv/riscv32-unknown-elf/lib\");\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
/* Read-only sections, merged into text segment: */\n\
|
|
PROVIDE (__executable_start = SEGMENT_START(\"text-segment\", 0x10000)); . = SEGMENT_START(\"text-segment\", 0x10000) + SIZEOF_HEADERS;\n\
|
|
.interp : { *(.interp) }\n\
|
|
.note.gnu.build-id : { *(.note.gnu.build-id) }\n\
|
|
.hash : { *(.hash) }\n\
|
|
.gnu.hash : { *(.gnu.hash) }\n\
|
|
.dynsym : { *(.dynsym) }\n\
|
|
.dynstr : { *(.dynstr) }\n\
|
|
.gnu.version : { *(.gnu.version) }\n\
|
|
.gnu.version_d : { *(.gnu.version_d) }\n\
|
|
.gnu.version_r : { *(.gnu.version_r) }\n\
|
|
.rela.dyn :\n\
|
|
{\n"
|
|
" *(.rela.init)\n\
|
|
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)\n\
|
|
*(.rela.fini)\n\
|
|
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)\n\
|
|
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)\n\
|
|
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)\n\
|
|
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)\n\
|
|
*(.rela.ctors)\n\
|
|
*(.rela.dtors)\n\
|
|
*(.rela.got)\n\
|
|
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)\n\
|
|
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)\n\
|
|
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)\n\
|
|
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)\n\
|
|
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)\n\
|
|
*(.rela.ifunc)\n\
|
|
}\n\
|
|
.rela.plt :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_start = .);\n\
|
|
*(.rela.iplt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_end = .);\n\
|
|
}\n\
|
|
.init :\n"
|
|
" {\n\
|
|
KEEP (*(SORT_NONE(.init)))\n\
|
|
}\n\
|
|
.plt : { *(.plt) *(.iplt) }\n\
|
|
.text :\n\
|
|
{\n\
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)\n\
|
|
*(.text.exit .text.exit.*)\n\
|
|
*(.text.startup .text.startup.*)\n\
|
|
*(.text.hot .text.hot.*)\n\
|
|
*(SORT(.text.sorted.*))\n\
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
PROVIDE (__etext = .);\n\
|
|
PROVIDE (_etext = .);\n\
|
|
PROVIDE (etext = .);\n\
|
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\n\
|
|
.rodata1 : { *(.rodata1) }\n\
|
|
.sdata2 :\n"
|
|
" {\n\
|
|
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)\n\
|
|
}\n\
|
|
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }\n\
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }\n\
|
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }\n\
|
|
/* Adjust the address for the data segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n\
|
|
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }\n\
|
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__tdata_start = .);\n\
|
|
*(.tdata .tdata.* .gnu.linkonce.td.*)\n\
|
|
}\n\
|
|
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\n"
|
|
" .preinit_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__preinit_array_start = .);\n\
|
|
KEEP (*(.preinit_array))\n\
|
|
PROVIDE_HIDDEN (__preinit_array_end = .);\n\
|
|
}\n\
|
|
.init_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__init_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))\n\
|
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))\n\
|
|
PROVIDE_HIDDEN (__init_array_end = .);\n\
|
|
}\n\
|
|
.fini_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__fini_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))\n\
|
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))\n\
|
|
PROVIDE_HIDDEN (__fini_array_end = .);\n\
|
|
}\n\
|
|
.ctors :\n\
|
|
{\n\
|
|
/* gcc uses crtbegin.o to find the start of\n\
|
|
the constructors, so we make sure it is\n\
|
|
first. Because this is a wildcard, it\n\
|
|
doesn't matter if the user does not\n\
|
|
actually link against crtbegin.o; the\n\
|
|
linker won't look for a file to match a\n\
|
|
wildcard. The wildcard also means that it\n\
|
|
doesn't matter which directory crtbegin.o\n\
|
|
is in. */\n\
|
|
KEEP (*crtbegin.o(.ctors))\n\
|
|
KEEP (*crtbegin?.o(.ctors))\n\
|
|
/* We don't want to include the .ctor section from\n\
|
|
the crtend.o file until after the sorted ctors.\n\
|
|
The .ctor section from the crtend file contains the\n\
|
|
end of ctors marker and it must be last */\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\n\
|
|
KEEP (*(SORT(.ctors.*)))\n\
|
|
KEEP (*(.ctors))\n\
|
|
}\n\
|
|
.dtors :\n\
|
|
{\n\
|
|
KEEP (*crtbegin.o(.dtors))\n\
|
|
KEEP (*crtbegin?.o(.dtors))\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\n\
|
|
KEEP (*(SORT(.dtors.*)))\n\
|
|
KEEP (*(.dtors))\n\
|
|
}\n\
|
|
.jcr : { KEEP (*(.jcr)) }\n\
|
|
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }\n\
|
|
.dynamic : { *(.dynamic) }\n\
|
|
. = DATA_SEGMENT_RELRO_END (0, .);\n\
|
|
.data :\n\
|
|
{\n\
|
|
__DATA_BEGIN__ = .;\n\
|
|
*(.data .data.* .gnu.linkonce.d.*)\n\
|
|
SORT(CONSTRUCTORS)\n\
|
|
}\n\
|
|
.data1 : { *(.data1) }\n\
|
|
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata :\n\
|
|
{\n\
|
|
__SDATA_BEGIN__ = .;\n\
|
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)\n\
|
|
*(.sdata .sdata.* .gnu.linkonce.s.*)\n\
|
|
}\n\
|
|
_edata = .; PROVIDE (edata = .);\n\
|
|
. = .;\n\
|
|
__bss_start = .;\n\
|
|
.sbss :\n\
|
|
{\n\
|
|
*(.dynsbss)\n\
|
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)\n\
|
|
*(.scommon)\n\
|
|
}\n\
|
|
.bss :\n\
|
|
{\n\
|
|
*(.dynbss)\n\
|
|
*(.bss .bss.* .gnu.linkonce.b.*)\n\
|
|
*(COMMON)\n\
|
|
/* Align here to ensure that the .bss section occupies space up to\n\
|
|
_end. Align after .bss to ensure correct alignment even if the\n\
|
|
.bss section disappears because there are no input sections.\n\
|
|
FIXME: Why do we need it? When there is no .bss section, we do not\n\
|
|
pad the .data section. */\n\
|
|
. = ALIGN(. != 0 ? 32 / 8 : 1);\n\
|
|
}\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
. = SEGMENT_START(\"ldata-segment\", .);\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
__BSS_END__ = .;\n\
|
|
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,\n\
|
|
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));\n\
|
|
_end = .; PROVIDE (end = .);\n\
|
|
. = DATA_SEGMENT_END (.);\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }\n\
|
|
}\n\n"
|
|
; else if (link_info.combreloc
|
|
&& link_info.separate_code) return
|
|
"/* Script for -z combreloc -z separate-code */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
ENTRY(_start)\n\
|
|
SEARCH_DIR(\"/opt/riscv/riscv32-unknown-elf/lib\");\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
PROVIDE (__executable_start = SEGMENT_START(\"text-segment\", 0x10000)); . = SEGMENT_START(\"text-segment\", 0x10000) + SIZEOF_HEADERS;\n\
|
|
.interp : { *(.interp) }\n\
|
|
.note.gnu.build-id : { *(.note.gnu.build-id) }\n\
|
|
.hash : { *(.hash) }\n\
|
|
.gnu.hash : { *(.gnu.hash) }\n\
|
|
.dynsym : { *(.dynsym) }\n\
|
|
.dynstr : { *(.dynstr) }\n\
|
|
.gnu.version : { *(.gnu.version) }\n\
|
|
.gnu.version_d : { *(.gnu.version_d) }\n\
|
|
.gnu.version_r : { *(.gnu.version_r) }\n\
|
|
.rela.dyn :\n\
|
|
{\n\
|
|
*(.rela.init)\n"
|
|
" *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)\n\
|
|
*(.rela.fini)\n\
|
|
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)\n\
|
|
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)\n\
|
|
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)\n\
|
|
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)\n\
|
|
*(.rela.ctors)\n\
|
|
*(.rela.dtors)\n\
|
|
*(.rela.got)\n\
|
|
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)\n\
|
|
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)\n\
|
|
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)\n\
|
|
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)\n\
|
|
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)\n\
|
|
*(.rela.ifunc)\n\
|
|
}\n\
|
|
.rela.plt :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_start = .);\n\
|
|
*(.rela.iplt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_end = .);\n\
|
|
}\n\
|
|
. = ALIGN(CONSTANT (MAXPAGESIZE));\n\
|
|
.init :\n"
|
|
" {\n\
|
|
KEEP (*(SORT_NONE(.init)))\n\
|
|
}\n\
|
|
.plt : { *(.plt) *(.iplt) }\n\
|
|
.text :\n\
|
|
{\n\
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)\n\
|
|
*(.text.exit .text.exit.*)\n\
|
|
*(.text.startup .text.startup.*)\n\
|
|
*(.text.hot .text.hot.*)\n\
|
|
*(SORT(.text.sorted.*))\n\
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
PROVIDE (__etext = .);\n\
|
|
PROVIDE (_etext = .);\n\
|
|
PROVIDE (etext = .);\n\
|
|
. = ALIGN(CONSTANT (MAXPAGESIZE));\n\
|
|
/* Adjust the address for the rodata segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n"
|
|
" . = SEGMENT_START(\"rodata-segment\", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));\n\
|
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\n\
|
|
.rodata1 : { *(.rodata1) }\n\
|
|
.sdata2 :\n\
|
|
{\n\
|
|
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)\n\
|
|
}\n\
|
|
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }\n\
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }\n\
|
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }\n\
|
|
/* Adjust the address for the data segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n\
|
|
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }\n\
|
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata :\n\
|
|
{\n"
|
|
" PROVIDE_HIDDEN (__tdata_start = .);\n\
|
|
*(.tdata .tdata.* .gnu.linkonce.td.*)\n\
|
|
}\n\
|
|
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\n\
|
|
.preinit_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__preinit_array_start = .);\n\
|
|
KEEP (*(.preinit_array))\n\
|
|
PROVIDE_HIDDEN (__preinit_array_end = .);\n\
|
|
}\n\
|
|
.init_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__init_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))\n\
|
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))\n\
|
|
PROVIDE_HIDDEN (__init_array_end = .);\n\
|
|
}\n\
|
|
.fini_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__fini_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))\n\
|
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))\n\
|
|
PROVIDE_HIDDEN (__fini_array_end = .);\n\
|
|
}\n\
|
|
.ctors :\n\
|
|
{\n\
|
|
/* gcc uses crtbegin.o to find the start of\n\
|
|
the constructors, so we make sure it is\n\
|
|
first. Because this is a wildcard, it\n\
|
|
doesn't matter if the user does not\n\
|
|
actually link against crtbegin.o; the\n\
|
|
linker won't look for a file to match a\n\
|
|
wildcard. The wildcard also means that it\n\
|
|
doesn't matter which directory crtbegin.o\n\
|
|
is in. */\n\
|
|
KEEP (*crtbegin.o(.ctors))\n\
|
|
KEEP (*crtbegin?.o(.ctors))\n\
|
|
/* We don't want to include the .ctor section from\n\
|
|
the crtend.o file until after the sorted ctors.\n\
|
|
The .ctor section from the crtend file contains the\n\
|
|
end of ctors marker and it must be last */\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\n\
|
|
KEEP (*(SORT(.ctors.*)))\n\
|
|
KEEP (*(.ctors))\n\
|
|
}\n\
|
|
.dtors :\n\
|
|
{\n\
|
|
KEEP (*crtbegin.o(.dtors))\n\
|
|
KEEP (*crtbegin?.o(.dtors))\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\n\
|
|
KEEP (*(SORT(.dtors.*)))\n\
|
|
KEEP (*(.dtors))\n\
|
|
}\n\
|
|
.jcr : { KEEP (*(.jcr)) }\n\
|
|
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }\n\
|
|
.dynamic : { *(.dynamic) }\n\
|
|
. = DATA_SEGMENT_RELRO_END (0, .);\n\
|
|
.data :\n\
|
|
{\n\
|
|
__DATA_BEGIN__ = .;\n\
|
|
*(.data .data.* .gnu.linkonce.d.*)\n\
|
|
SORT(CONSTRUCTORS)\n\
|
|
}\n\
|
|
.data1 : { *(.data1) }\n\
|
|
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata :\n\
|
|
{\n\
|
|
__SDATA_BEGIN__ = .;\n\
|
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)\n\
|
|
*(.sdata .sdata.* .gnu.linkonce.s.*)\n\
|
|
}\n\
|
|
_edata = .; PROVIDE (edata = .);\n\
|
|
. = .;\n\
|
|
__bss_start = .;\n\
|
|
.sbss :\n\
|
|
{\n\
|
|
*(.dynsbss)\n\
|
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)\n\
|
|
*(.scommon)\n\
|
|
}\n\
|
|
.bss :\n\
|
|
{\n\
|
|
*(.dynbss)\n\
|
|
*(.bss .bss.* .gnu.linkonce.b.*)\n\
|
|
*(COMMON)\n\
|
|
/* Align here to ensure that the .bss section occupies space up to\n\
|
|
_end. Align after .bss to ensure correct alignment even if the\n\
|
|
.bss section disappears because there are no input sections.\n\
|
|
FIXME: Why do we need it? When there is no .bss section, we do not\n\
|
|
pad the .data section. */\n\
|
|
. = ALIGN(. != 0 ? 32 / 8 : 1);\n\
|
|
}\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
. = SEGMENT_START(\"ldata-segment\", .);\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
__BSS_END__ = .;\n\
|
|
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,\n\
|
|
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));\n\
|
|
_end = .; PROVIDE (end = .);\n\
|
|
. = DATA_SEGMENT_END (.);\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }\n\
|
|
}\n\n"
|
|
; else if (link_info.combreloc) return
|
|
"/* Script for -z combreloc */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
ENTRY(_start)\n\
|
|
SEARCH_DIR(\"/opt/riscv/riscv32-unknown-elf/lib\");\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
/* Read-only sections, merged into text segment: */\n\
|
|
PROVIDE (__executable_start = SEGMENT_START(\"text-segment\", 0x10000)); . = SEGMENT_START(\"text-segment\", 0x10000) + SIZEOF_HEADERS;\n\
|
|
.interp : { *(.interp) }\n\
|
|
.note.gnu.build-id : { *(.note.gnu.build-id) }\n\
|
|
.hash : { *(.hash) }\n\
|
|
.gnu.hash : { *(.gnu.hash) }\n\
|
|
.dynsym : { *(.dynsym) }\n\
|
|
.dynstr : { *(.dynstr) }\n\
|
|
.gnu.version : { *(.gnu.version) }\n\
|
|
.gnu.version_d : { *(.gnu.version_d) }\n\
|
|
.gnu.version_r : { *(.gnu.version_r) }\n\
|
|
.rela.dyn :\n\
|
|
{\n"
|
|
" *(.rela.init)\n\
|
|
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)\n\
|
|
*(.rela.fini)\n\
|
|
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)\n\
|
|
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)\n\
|
|
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)\n\
|
|
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)\n\
|
|
*(.rela.ctors)\n\
|
|
*(.rela.dtors)\n\
|
|
*(.rela.got)\n\
|
|
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)\n\
|
|
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)\n\
|
|
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)\n\
|
|
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)\n\
|
|
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)\n\
|
|
*(.rela.ifunc)\n\
|
|
}\n\
|
|
.rela.plt :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_start = .);\n\
|
|
*(.rela.iplt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_end = .);\n\
|
|
}\n\
|
|
.init :\n"
|
|
" {\n\
|
|
KEEP (*(SORT_NONE(.init)))\n\
|
|
}\n\
|
|
.plt : { *(.plt) *(.iplt) }\n\
|
|
.text :\n\
|
|
{\n\
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)\n\
|
|
*(.text.exit .text.exit.*)\n\
|
|
*(.text.startup .text.startup.*)\n\
|
|
*(.text.hot .text.hot.*)\n\
|
|
*(SORT(.text.sorted.*))\n\
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
PROVIDE (__etext = .);\n\
|
|
PROVIDE (_etext = .);\n\
|
|
PROVIDE (etext = .);\n\
|
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\n\
|
|
.rodata1 : { *(.rodata1) }\n\
|
|
.sdata2 :\n"
|
|
" {\n\
|
|
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)\n\
|
|
}\n\
|
|
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }\n\
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }\n\
|
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }\n\
|
|
/* Adjust the address for the data segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n\
|
|
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }\n\
|
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__tdata_start = .);\n\
|
|
*(.tdata .tdata.* .gnu.linkonce.td.*)\n\
|
|
}\n\
|
|
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\n"
|
|
" .preinit_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__preinit_array_start = .);\n\
|
|
KEEP (*(.preinit_array))\n\
|
|
PROVIDE_HIDDEN (__preinit_array_end = .);\n\
|
|
}\n\
|
|
.init_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__init_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))\n\
|
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))\n\
|
|
PROVIDE_HIDDEN (__init_array_end = .);\n\
|
|
}\n\
|
|
.fini_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__fini_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))\n\
|
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))\n\
|
|
PROVIDE_HIDDEN (__fini_array_end = .);\n\
|
|
}\n\
|
|
.ctors :\n\
|
|
{\n\
|
|
/* gcc uses crtbegin.o to find the start of\n\
|
|
the constructors, so we make sure it is\n\
|
|
first. Because this is a wildcard, it\n\
|
|
doesn't matter if the user does not\n\
|
|
actually link against crtbegin.o; the\n\
|
|
linker won't look for a file to match a\n\
|
|
wildcard. The wildcard also means that it\n\
|
|
doesn't matter which directory crtbegin.o\n\
|
|
is in. */\n\
|
|
KEEP (*crtbegin.o(.ctors))\n\
|
|
KEEP (*crtbegin?.o(.ctors))\n\
|
|
/* We don't want to include the .ctor section from\n\
|
|
the crtend.o file until after the sorted ctors.\n\
|
|
The .ctor section from the crtend file contains the\n\
|
|
end of ctors marker and it must be last */\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\n\
|
|
KEEP (*(SORT(.ctors.*)))\n\
|
|
KEEP (*(.ctors))\n\
|
|
}\n\
|
|
.dtors :\n\
|
|
{\n\
|
|
KEEP (*crtbegin.o(.dtors))\n\
|
|
KEEP (*crtbegin?.o(.dtors))\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\n\
|
|
KEEP (*(SORT(.dtors.*)))\n\
|
|
KEEP (*(.dtors))\n\
|
|
}\n\
|
|
.jcr : { KEEP (*(.jcr)) }\n\
|
|
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }\n\
|
|
.dynamic : { *(.dynamic) }\n\
|
|
. = DATA_SEGMENT_RELRO_END (0, .);\n\
|
|
.data :\n\
|
|
{\n\
|
|
__DATA_BEGIN__ = .;\n\
|
|
*(.data .data.* .gnu.linkonce.d.*)\n\
|
|
SORT(CONSTRUCTORS)\n\
|
|
}\n\
|
|
.data1 : { *(.data1) }\n\
|
|
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata :\n\
|
|
{\n\
|
|
__SDATA_BEGIN__ = .;\n\
|
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)\n\
|
|
*(.sdata .sdata.* .gnu.linkonce.s.*)\n\
|
|
}\n\
|
|
_edata = .; PROVIDE (edata = .);\n\
|
|
. = .;\n\
|
|
__bss_start = .;\n\
|
|
.sbss :\n\
|
|
{\n\
|
|
*(.dynsbss)\n\
|
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)\n\
|
|
*(.scommon)\n\
|
|
}\n\
|
|
.bss :\n\
|
|
{\n\
|
|
*(.dynbss)\n\
|
|
*(.bss .bss.* .gnu.linkonce.b.*)\n\
|
|
*(COMMON)\n\
|
|
/* Align here to ensure that the .bss section occupies space up to\n\
|
|
_end. Align after .bss to ensure correct alignment even if the\n\
|
|
.bss section disappears because there are no input sections.\n\
|
|
FIXME: Why do we need it? When there is no .bss section, we do not\n\
|
|
pad the .data section. */\n\
|
|
. = ALIGN(. != 0 ? 32 / 8 : 1);\n\
|
|
}\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
. = SEGMENT_START(\"ldata-segment\", .);\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
__BSS_END__ = .;\n\
|
|
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,\n\
|
|
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));\n\
|
|
_end = .; PROVIDE (end = .);\n\
|
|
. = DATA_SEGMENT_END (.);\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }\n\
|
|
}\n\n"
|
|
; else if (link_info.separate_code) return
|
|
"/* Script for -z separate-code */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
ENTRY(_start)\n\
|
|
SEARCH_DIR(\"/opt/riscv/riscv32-unknown-elf/lib\");\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
PROVIDE (__executable_start = SEGMENT_START(\"text-segment\", 0x10000)); . = SEGMENT_START(\"text-segment\", 0x10000) + SIZEOF_HEADERS;\n\
|
|
.interp : { *(.interp) }\n\
|
|
.note.gnu.build-id : { *(.note.gnu.build-id) }\n\
|
|
.hash : { *(.hash) }\n\
|
|
.gnu.hash : { *(.gnu.hash) }\n\
|
|
.dynsym : { *(.dynsym) }\n\
|
|
.dynstr : { *(.dynstr) }\n\
|
|
.gnu.version : { *(.gnu.version) }\n\
|
|
.gnu.version_d : { *(.gnu.version_d) }\n\
|
|
.gnu.version_r : { *(.gnu.version_r) }\n\
|
|
.rela.init : { *(.rela.init) }\n\
|
|
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }\n\
|
|
.rela.fini : { *(.rela.fini) }\n"
|
|
" .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }\n\
|
|
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }\n\
|
|
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }\n\
|
|
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }\n\
|
|
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }\n\
|
|
.rela.ctors : { *(.rela.ctors) }\n\
|
|
.rela.dtors : { *(.rela.dtors) }\n\
|
|
.rela.got : { *(.rela.got) }\n\
|
|
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }\n\
|
|
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }\n\
|
|
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }\n\
|
|
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }\n\
|
|
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }\n\
|
|
.rela.ifunc : { *(.rela.ifunc) }\n\
|
|
.rela.plt :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_start = .);\n\
|
|
*(.rela.iplt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_end = .);\n\
|
|
}\n\
|
|
. = ALIGN(CONSTANT (MAXPAGESIZE));\n\
|
|
.init :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.init)))\n"
|
|
" }\n\
|
|
.plt : { *(.plt) *(.iplt) }\n\
|
|
.text :\n\
|
|
{\n\
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)\n\
|
|
*(.text.exit .text.exit.*)\n\
|
|
*(.text.startup .text.startup.*)\n\
|
|
*(.text.hot .text.hot.*)\n\
|
|
*(SORT(.text.sorted.*))\n\
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
PROVIDE (__etext = .);\n\
|
|
PROVIDE (_etext = .);\n\
|
|
PROVIDE (etext = .);\n\
|
|
. = ALIGN(CONSTANT (MAXPAGESIZE));\n\
|
|
/* Adjust the address for the rodata segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n\
|
|
. = SEGMENT_START(\"rodata-segment\", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));\n\
|
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\n"
|
|
" .rodata1 : { *(.rodata1) }\n\
|
|
.sdata2 :\n\
|
|
{\n\
|
|
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)\n\
|
|
}\n\
|
|
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }\n\
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }\n\
|
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }\n\
|
|
/* Adjust the address for the data segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n\
|
|
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }\n\
|
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__tdata_start = .);\n\
|
|
*(.tdata .tdata.* .gnu.linkonce.td.*)\n"
|
|
" }\n\
|
|
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\n\
|
|
.preinit_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__preinit_array_start = .);\n\
|
|
KEEP (*(.preinit_array))\n\
|
|
PROVIDE_HIDDEN (__preinit_array_end = .);\n\
|
|
}\n\
|
|
.init_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__init_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))\n\
|
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))\n\
|
|
PROVIDE_HIDDEN (__init_array_end = .);\n\
|
|
}\n\
|
|
.fini_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__fini_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))\n\
|
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))\n\
|
|
PROVIDE_HIDDEN (__fini_array_end = .);\n\
|
|
}\n\
|
|
.ctors :\n\
|
|
{\n\
|
|
/* gcc uses crtbegin.o to find the start of\n\
|
|
the constructors, so we make sure it is\n\
|
|
first. Because this is a wildcard, it\n\
|
|
doesn't matter if the user does not\n\
|
|
actually link against crtbegin.o; the\n\
|
|
linker won't look for a file to match a\n\
|
|
wildcard. The wildcard also means that it\n\
|
|
doesn't matter which directory crtbegin.o\n\
|
|
is in. */\n\
|
|
KEEP (*crtbegin.o(.ctors))\n\
|
|
KEEP (*crtbegin?.o(.ctors))\n\
|
|
/* We don't want to include the .ctor section from\n\
|
|
the crtend.o file until after the sorted ctors.\n\
|
|
The .ctor section from the crtend file contains the\n\
|
|
end of ctors marker and it must be last */\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\n\
|
|
KEEP (*(SORT(.ctors.*)))\n\
|
|
KEEP (*(.ctors))\n\
|
|
}\n\
|
|
.dtors :\n\
|
|
{\n\
|
|
KEEP (*crtbegin.o(.dtors))\n\
|
|
KEEP (*crtbegin?.o(.dtors))\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\n\
|
|
KEEP (*(SORT(.dtors.*)))\n\
|
|
KEEP (*(.dtors))\n\
|
|
}\n\
|
|
.jcr : { KEEP (*(.jcr)) }\n\
|
|
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }\n\
|
|
.dynamic : { *(.dynamic) }\n\
|
|
. = DATA_SEGMENT_RELRO_END (0, .);\n\
|
|
.data :\n\
|
|
{\n\
|
|
__DATA_BEGIN__ = .;\n\
|
|
*(.data .data.* .gnu.linkonce.d.*)\n\
|
|
SORT(CONSTRUCTORS)\n\
|
|
}\n\
|
|
.data1 : { *(.data1) }\n\
|
|
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata :\n\
|
|
{\n\
|
|
__SDATA_BEGIN__ = .;\n\
|
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)\n\
|
|
*(.sdata .sdata.* .gnu.linkonce.s.*)\n\
|
|
}\n\
|
|
_edata = .; PROVIDE (edata = .);\n\
|
|
. = .;\n\
|
|
__bss_start = .;\n\
|
|
.sbss :\n\
|
|
{\n\
|
|
*(.dynsbss)\n\
|
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)\n\
|
|
*(.scommon)\n\
|
|
}\n\
|
|
.bss :\n\
|
|
{\n\
|
|
*(.dynbss)\n\
|
|
*(.bss .bss.* .gnu.linkonce.b.*)\n\
|
|
*(COMMON)\n\
|
|
/* Align here to ensure that the .bss section occupies space up to\n\
|
|
_end. Align after .bss to ensure correct alignment even if the\n\
|
|
.bss section disappears because there are no input sections.\n\
|
|
FIXME: Why do we need it? When there is no .bss section, we do not\n\
|
|
pad the .data section. */\n\
|
|
. = ALIGN(. != 0 ? 32 / 8 : 1);\n\
|
|
}\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
. = SEGMENT_START(\"ldata-segment\", .);\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
__BSS_END__ = .;\n\
|
|
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,\n\
|
|
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));\n\
|
|
_end = .; PROVIDE (end = .);\n\
|
|
. = DATA_SEGMENT_END (.);\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }\n\
|
|
}\n\n"
|
|
; else return
|
|
"/* Default linker script, for normal executables */\n\
|
|
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.\n\
|
|
Copying and distribution of this script, with or without modification,\n\
|
|
are permitted in any medium without royalty provided the copyright\n\
|
|
notice and this notice are preserved. */\n\
|
|
OUTPUT_FORMAT(\"elf32-bigriscv\", \"elf32-bigriscv\",\n\
|
|
\"elf32-bigriscv\")\n\
|
|
OUTPUT_ARCH(riscv)\n\
|
|
ENTRY(_start)\n\
|
|
SEARCH_DIR(\"/opt/riscv/riscv32-unknown-elf/lib\");\n\
|
|
SECTIONS\n\
|
|
{\n\
|
|
/* Read-only sections, merged into text segment: */\n\
|
|
PROVIDE (__executable_start = SEGMENT_START(\"text-segment\", 0x10000)); . = SEGMENT_START(\"text-segment\", 0x10000) + SIZEOF_HEADERS;\n\
|
|
.interp : { *(.interp) }\n\
|
|
.note.gnu.build-id : { *(.note.gnu.build-id) }\n\
|
|
.hash : { *(.hash) }\n\
|
|
.gnu.hash : { *(.gnu.hash) }\n\
|
|
.dynsym : { *(.dynsym) }\n\
|
|
.dynstr : { *(.dynstr) }\n\
|
|
.gnu.version : { *(.gnu.version) }\n\
|
|
.gnu.version_d : { *(.gnu.version_d) }\n\
|
|
.gnu.version_r : { *(.gnu.version_r) }\n\
|
|
.rela.init : { *(.rela.init) }\n\
|
|
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }\n"
|
|
" .rela.fini : { *(.rela.fini) }\n\
|
|
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }\n\
|
|
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }\n\
|
|
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }\n\
|
|
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }\n\
|
|
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }\n\
|
|
.rela.ctors : { *(.rela.ctors) }\n\
|
|
.rela.dtors : { *(.rela.dtors) }\n\
|
|
.rela.got : { *(.rela.got) }\n\
|
|
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }\n\
|
|
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }\n\
|
|
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }\n\
|
|
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }\n\
|
|
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }\n\
|
|
.rela.ifunc : { *(.rela.ifunc) }\n\
|
|
.rela.plt :\n\
|
|
{\n\
|
|
*(.rela.plt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_start = .);\n\
|
|
*(.rela.iplt)\n\
|
|
PROVIDE_HIDDEN (__rela_iplt_end = .);\n\
|
|
}\n\
|
|
.init :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.init)))\n"
|
|
" }\n\
|
|
.plt : { *(.plt) *(.iplt) }\n\
|
|
.text :\n\
|
|
{\n\
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)\n\
|
|
*(.text.exit .text.exit.*)\n\
|
|
*(.text.startup .text.startup.*)\n\
|
|
*(.text.hot .text.hot.*)\n\
|
|
*(SORT(.text.sorted.*))\n\
|
|
*(.text .stub .text.* .gnu.linkonce.t.*)\n\
|
|
/* .gnu.warning sections are handled specially by elf.em. */\n\
|
|
*(.gnu.warning)\n\
|
|
}\n\
|
|
.fini :\n\
|
|
{\n\
|
|
KEEP (*(SORT_NONE(.fini)))\n\
|
|
}\n\
|
|
PROVIDE (__etext = .);\n\
|
|
PROVIDE (_etext = .);\n\
|
|
PROVIDE (etext = .);\n\
|
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\n\
|
|
.rodata1 : { *(.rodata1) }\n\
|
|
.sdata2 :\n\
|
|
{\n\
|
|
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)\n"
|
|
" }\n\
|
|
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }\n\
|
|
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }\n\
|
|
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }\n\
|
|
/* These sections are generated by the Sun/Oracle C++ compiler. */\n\
|
|
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }\n\
|
|
/* Adjust the address for the data segment. We want to adjust up to\n\
|
|
the same address within the page on the next page up. */\n\
|
|
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));\n\
|
|
/* Exception handling */\n\
|
|
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n\
|
|
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }\n\
|
|
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\n\
|
|
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }\n\
|
|
/* Thread Local Storage sections */\n\
|
|
.tdata :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__tdata_start = .);\n\
|
|
*(.tdata .tdata.* .gnu.linkonce.td.*)\n\
|
|
}\n\
|
|
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\n\
|
|
.preinit_array :\n\
|
|
{\n"
|
|
" PROVIDE_HIDDEN (__preinit_array_start = .);\n\
|
|
KEEP (*(.preinit_array))\n\
|
|
PROVIDE_HIDDEN (__preinit_array_end = .);\n\
|
|
}\n\
|
|
.init_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__init_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))\n\
|
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))\n\
|
|
PROVIDE_HIDDEN (__init_array_end = .);\n\
|
|
}\n\
|
|
.fini_array :\n\
|
|
{\n\
|
|
PROVIDE_HIDDEN (__fini_array_start = .);\n\
|
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))\n\
|
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))\n\
|
|
PROVIDE_HIDDEN (__fini_array_end = .);\n\
|
|
}\n\
|
|
.ctors :\n\
|
|
{\n\
|
|
/* gcc uses crtbegin.o to find the start of\n\
|
|
the constructors, so we make sure it is\n\
|
|
first. Because this is a wildcard, it\n\
|
|
doesn't matter if the user does not\n\
|
|
actually link against crtbegin.o; the\n\
|
|
linker won't look for a file to match a\n\
|
|
wildcard. The wildcard also means that it\n\
|
|
doesn't matter which directory crtbegin.o\n\
|
|
is in. */\n\
|
|
KEEP (*crtbegin.o(.ctors))\n\
|
|
KEEP (*crtbegin?.o(.ctors))\n\
|
|
/* We don't want to include the .ctor section from\n\
|
|
the crtend.o file until after the sorted ctors.\n\
|
|
The .ctor section from the crtend file contains the\n\
|
|
end of ctors marker and it must be last */\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\n\
|
|
KEEP (*(SORT(.ctors.*)))\n\
|
|
KEEP (*(.ctors))\n\
|
|
}\n\
|
|
.dtors :\n\
|
|
{\n\
|
|
KEEP (*crtbegin.o(.dtors))\n\
|
|
KEEP (*crtbegin?.o(.dtors))\n\
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\n\
|
|
KEEP (*(SORT(.dtors.*)))\n\
|
|
KEEP (*(.dtors))\n\
|
|
}\n\
|
|
.jcr : { KEEP (*(.jcr)) }\n\
|
|
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }\n\
|
|
.dynamic : { *(.dynamic) }\n\
|
|
. = DATA_SEGMENT_RELRO_END (0, .);\n\
|
|
.data :\n\
|
|
{\n\
|
|
__DATA_BEGIN__ = .;\n\
|
|
*(.data .data.* .gnu.linkonce.d.*)\n\
|
|
SORT(CONSTRUCTORS)\n\
|
|
}\n\
|
|
.data1 : { *(.data1) }\n\
|
|
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }\n\
|
|
/* We want the small data sections together, so single-instruction offsets\n\
|
|
can access them all, and initialized data all before uninitialized, so\n\
|
|
we can shorten the on-disk segment size. */\n\
|
|
.sdata :\n\
|
|
{\n\
|
|
__SDATA_BEGIN__ = .;\n\
|
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)\n\
|
|
*(.sdata .sdata.* .gnu.linkonce.s.*)\n\
|
|
}\n\
|
|
_edata = .; PROVIDE (edata = .);\n\
|
|
. = .;\n\
|
|
__bss_start = .;\n\
|
|
.sbss :\n\
|
|
{\n\
|
|
*(.dynsbss)\n\
|
|
*(.sbss .sbss.* .gnu.linkonce.sb.*)\n\
|
|
*(.scommon)\n\
|
|
}\n\
|
|
.bss :\n\
|
|
{\n\
|
|
*(.dynbss)\n\
|
|
*(.bss .bss.* .gnu.linkonce.b.*)\n\
|
|
*(COMMON)\n\
|
|
/* Align here to ensure that the .bss section occupies space up to\n\
|
|
_end. Align after .bss to ensure correct alignment even if the\n\
|
|
.bss section disappears because there are no input sections.\n\
|
|
FIXME: Why do we need it? When there is no .bss section, we do not\n\
|
|
pad the .data section. */\n\
|
|
. = ALIGN(. != 0 ? 32 / 8 : 1);\n\
|
|
}\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
. = SEGMENT_START(\"ldata-segment\", .);\n\
|
|
. = ALIGN(32 / 8);\n\
|
|
__BSS_END__ = .;\n\
|
|
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,\n\
|
|
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));\n\
|
|
_end = .; PROVIDE (end = .);\n\
|
|
. = DATA_SEGMENT_END (.);\n\
|
|
/* Stabs debugging sections. */\n\
|
|
.stab 0 : { *(.stab) }\n\
|
|
.stabstr 0 : { *(.stabstr) }\n\
|
|
.stab.excl 0 : { *(.stab.excl) }\n\
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }\n\
|
|
.stab.index 0 : { *(.stab.index) }\n\
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }\n\
|
|
.comment 0 : { *(.comment) }\n\
|
|
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }\n\
|
|
/* DWARF debug sections.\n\
|
|
Symbols in the DWARF debugging sections are relative to the beginning\n\
|
|
of the section so we begin them at 0. */\n\
|
|
/* DWARF 1. */\n\
|
|
.debug 0 : { *(.debug) }\n\
|
|
.line 0 : { *(.line) }\n\
|
|
/* GNU DWARF 1 extensions. */\n\
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }\n\
|
|
/* DWARF 1.1 and DWARF 2. */\n\
|
|
.debug_aranges 0 : { *(.debug_aranges) }\n\
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }\n\
|
|
/* DWARF 2. */\n\
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }\n\
|
|
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }\n\
|
|
.debug_frame 0 : { *(.debug_frame) }\n\
|
|
.debug_str 0 : { *(.debug_str) }\n\
|
|
.debug_loc 0 : { *(.debug_loc) }\n\
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }\n\
|
|
/* SGI/MIPS DWARF 2 extensions. */\n\
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }\n\
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }\n\
|
|
.debug_typenames 0 : { *(.debug_typenames) }\n\
|
|
.debug_varnames 0 : { *(.debug_varnames) }\n\
|
|
/* DWARF 3. */\n\
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }\n\
|
|
.debug_ranges 0 : { *(.debug_ranges) }\n\
|
|
/* DWARF 5. */\n\
|
|
.debug_addr 0 : { *(.debug_addr) }\n\
|
|
.debug_line_str 0 : { *(.debug_line_str) }\n\
|
|
.debug_loclists 0 : { *(.debug_loclists) }\n\
|
|
.debug_macro 0 : { *(.debug_macro) }\n\
|
|
.debug_names 0 : { *(.debug_names) }\n\
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }\n\
|
|
.debug_str_offsets 0 : { *(.debug_str_offsets) }\n\
|
|
.debug_sup 0 : { *(.debug_sup) }\n\
|
|
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n\
|
|
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }\n\
|
|
}\n\n"
|
|
; }
|
|
|
|
enum elf_options
|
|
{
|
|
OPTION_DISABLE_NEW_DTAGS = 400,
|
|
OPTION_ENABLE_NEW_DTAGS,
|
|
OPTION_GROUP,
|
|
OPTION_EH_FRAME_HDR,
|
|
OPTION_NO_EH_FRAME_HDR,
|
|
OPTION_EXCLUDE_LIBS,
|
|
OPTION_HASH_STYLE,
|
|
OPTION_BUILD_ID,
|
|
OPTION_PACKAGE_METADATA,
|
|
OPTION_AUDIT,
|
|
OPTION_COMPRESS_DEBUG
|
|
};
|
|
|
|
static void
|
|
gldelf32briscv_add_options
|
|
(int ns, char **shortopts, int nl, struct option **longopts,
|
|
int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
|
|
{
|
|
static const char xtra_short[] = "z:";
|
|
static const struct option xtra_long[] = {
|
|
{"build-id", optional_argument, NULL, OPTION_BUILD_ID},
|
|
{"package-metadata", optional_argument, NULL, OPTION_PACKAGE_METADATA},
|
|
{"compress-debug-sections", required_argument, NULL, OPTION_COMPRESS_DEBUG},
|
|
{NULL, no_argument, NULL, 0}
|
|
};
|
|
|
|
*shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
|
|
memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
|
|
*longopts = (struct option *)
|
|
xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
|
|
memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
|
|
}
|
|
|
|
#define DEFAULT_BUILD_ID_STYLE "sha1"
|
|
|
|
static bool
|
|
gldelf32briscv_handle_option (int optc)
|
|
{
|
|
switch (optc)
|
|
{
|
|
default:
|
|
return false;
|
|
|
|
case OPTION_BUILD_ID:
|
|
free ((char *) ldelf_emit_note_gnu_build_id);
|
|
ldelf_emit_note_gnu_build_id = NULL;
|
|
if (optarg == NULL)
|
|
optarg = DEFAULT_BUILD_ID_STYLE;
|
|
if (strcmp (optarg, "none"))
|
|
ldelf_emit_note_gnu_build_id = xstrdup (optarg);
|
|
break;
|
|
|
|
case OPTION_PACKAGE_METADATA:
|
|
free ((char *) ldelf_emit_note_fdo_package_metadata);
|
|
ldelf_emit_note_fdo_package_metadata = NULL;
|
|
if (optarg != NULL && strlen(optarg) > 0)
|
|
ldelf_emit_note_fdo_package_metadata = xstrdup (optarg);
|
|
break;
|
|
|
|
case OPTION_COMPRESS_DEBUG:
|
|
if (strcasecmp (optarg, "none") == 0)
|
|
link_info.compress_debug = COMPRESS_DEBUG_NONE;
|
|
else if (strcasecmp (optarg, "zlib") == 0)
|
|
link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
|
|
else if (strcasecmp (optarg, "zlib-gnu") == 0)
|
|
link_info.compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
|
|
else if (strcasecmp (optarg, "zlib-gabi") == 0)
|
|
link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
|
|
else
|
|
einfo (_("%F%P: invalid --compress-debug-sections option: `%s'\n"),
|
|
optarg);
|
|
break;
|
|
case 'z':
|
|
if (strcmp (optarg, "defs") == 0)
|
|
link_info.unresolved_syms_in_objects = RM_DIAGNOSE;
|
|
else if (strcmp (optarg, "undefs") == 0)
|
|
link_info.unresolved_syms_in_objects = RM_IGNORE;
|
|
else if (strcmp (optarg, "muldefs") == 0)
|
|
link_info.allow_multiple_definition = true;
|
|
else if (startswith (optarg, "max-page-size="))
|
|
{
|
|
char *end;
|
|
|
|
link_info.maxpagesize = strtoul (optarg + 14, &end, 0);
|
|
if (*end
|
|
|| (link_info.maxpagesize & (link_info.maxpagesize - 1)) != 0)
|
|
einfo (_("%F%P: invalid maximum page size `%s'\n"),
|
|
optarg + 14);
|
|
link_info.maxpagesize_is_set = true;
|
|
}
|
|
else if (startswith (optarg, "common-page-size="))
|
|
{
|
|
char *end;
|
|
link_info.commonpagesize = strtoul (optarg + 17, &end, 0);
|
|
if (*end
|
|
|| (link_info.commonpagesize & (link_info.commonpagesize - 1)) != 0)
|
|
einfo (_("%F%P: invalid common page size `%s'\n"),
|
|
optarg + 17);
|
|
link_info.commonpagesize_is_set = true;
|
|
}
|
|
else if (startswith (optarg, "stack-size="))
|
|
{
|
|
char *end;
|
|
link_info.stacksize = strtoul (optarg + 11, &end, 0);
|
|
if (*end || link_info.stacksize < 0)
|
|
einfo (_("%F%P: invalid stack size `%s'\n"), optarg + 11);
|
|
if (!link_info.stacksize)
|
|
/* Use -1 for explicit no-stack, because zero means
|
|
'default'. */
|
|
link_info.stacksize = -1;
|
|
}
|
|
else if (strcmp (optarg, "execstack") == 0)
|
|
{
|
|
link_info.execstack = true;
|
|
link_info.noexecstack = false;
|
|
}
|
|
else if (strcmp (optarg, "noexecstack") == 0)
|
|
{
|
|
link_info.noexecstack = true;
|
|
link_info.execstack = false;
|
|
}
|
|
else if (strcmp (optarg, "unique-symbol") == 0)
|
|
link_info.unique_symbol = true;
|
|
else if (strcmp (optarg, "nounique-symbol") == 0)
|
|
link_info.unique_symbol = false;
|
|
else if (strcmp (optarg, "globalaudit") == 0)
|
|
{
|
|
link_info.flags_1 |= DF_1_GLOBAUDIT;
|
|
}
|
|
else if (startswith (optarg, "start-stop-gc"))
|
|
link_info.start_stop_gc = true;
|
|
else if (startswith (optarg, "nostart-stop-gc"))
|
|
link_info.start_stop_gc = false;
|
|
else if (startswith (optarg, "start-stop-visibility="))
|
|
{
|
|
if (strcmp (optarg, "start-stop-visibility=default") == 0)
|
|
link_info.start_stop_visibility = STV_DEFAULT;
|
|
else if (strcmp (optarg, "start-stop-visibility=internal") == 0)
|
|
link_info.start_stop_visibility = STV_INTERNAL;
|
|
else if (strcmp (optarg, "start-stop-visibility=hidden") == 0)
|
|
link_info.start_stop_visibility = STV_HIDDEN;
|
|
else if (strcmp (optarg, "start-stop-visibility=protected") == 0)
|
|
link_info.start_stop_visibility = STV_PROTECTED;
|
|
else
|
|
einfo (_("%F%P: invalid visibility in `-z %s'; "
|
|
"must be default, internal, hidden, or protected"),
|
|
optarg);
|
|
}
|
|
else
|
|
einfo (_("%P: warning: -z %s ignored\n"), optarg);
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
struct ld_emulation_xfer_struct ld_elf32briscv_emulation =
|
|
{
|
|
gldelf32briscv_before_parse,
|
|
syslib_default,
|
|
hll_default,
|
|
ldelf_after_parse,
|
|
gldelf32briscv_before_plugin_all_symbols_read,
|
|
gldelf32briscv_after_open,
|
|
after_check_relocs_default,
|
|
ldelf_before_place_orphans,
|
|
gldelf32briscv_after_allocation,
|
|
ldelf_set_output_arch,
|
|
ldemul_default_target,
|
|
riscv_elf_before_allocation,
|
|
gldelf32briscv_get_script,
|
|
"elf32briscv",
|
|
"elf32-bigriscv",
|
|
finish_default,
|
|
riscv_create_output_section_statements,
|
|
ldelf_open_dynamic_archive,
|
|
ldelf_place_orphan,
|
|
NULL,
|
|
NULL,
|
|
gldelf32briscv_add_options,
|
|
gldelf32briscv_handle_option,
|
|
NULL,
|
|
NULL,
|
|
ldelf_load_symbols,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
ldelf_emit_ctf_early,
|
|
ldelf_acquire_strings_for_ctf,
|
|
ldelf_new_dynsym_for_ctf,
|
|
NULL
|
|
};
|