mirror of
https://github.com/apache/nuttx.git
synced 2026-09-11 03:16:45 +00:00
With CONFIG_FDPIC selected, a module built by apps/Application.mk is now an FDPIC shared object. Nothing about how a module is written or built changes: the same MODULE = m in the same Makefile, the same crt0 and the same linker script. Two things differ from the position independent build beside it. The compiler is told -mfdpic -fPIC, and the link is done by an arm-uclinuxfdpiceabi linker. The stock arm-none-eabi compiler emits correct FDPIC objects for both C and C++, so only the link needs it: the stock linker carries the armelf emulation alone and would turn every import into an R_ARM_JUMP_SLOT, one word, where the ABI wants an R_ARM_FUNCDESC_VALUE, which is two, a code address and the data base that goes with it. Such a module links cleanly and then calls out of itself with the caller's data base still in r9. That linker is in the CI image. gnu-elf.ld.in gains the two segments an FDPIC module needs, under CONFIG_FDPIC, because the loader places its read-only and writable segments independently, and names .dynamic, because a shared object is bound through it. The sections themselves are untouched and so are the symbols crt0.c walks, so one script serves both and both build systems get it. .bss moves to the end of the script, for every configuration and not only FDPIC. It held no file content but sat ahead of .got and .dynamic, which do, so the writable segment's p_filesz had to span it and the module file carried the whole of .bss. A module with 16 KiB of .bss went from 26724 to 10340 bytes, and its writable segment from p_filesz 0x40ac to 0xac against an unchanged p_memsz. The loader reads p_filesz off the media, so it read those bytes too. Built for mps3-an547:picostest with apps/examples/elf, CONFIG_FDPIC both ways. With it on, every module in apps/bin is ARM FDPIC with two PT_LOAD segments and enters at _start; hello++3, which has a static C++ object, carries DT_INIT_ARRAY and DT_FINI_ARRAY. With it off the generated script has no PHDRS and the modules are what they were. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
177 lines
4.3 KiB
Text
177 lines
4.3 KiB
Text
/****************************************************************************
|
|
* libs/libc/elf/gnu-elf.ld.in
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_BINFMT_ELF_EXECUTABLE)
|
|
# define __ASSEMBLY__
|
|
# include <nuttx/addrenv.h>
|
|
|
|
# define TEXT CONFIG_ARCH_TEXT_VBASE
|
|
# define DATA CONFIG_ARCH_DATA_VBASE + ARCH_DATA_RESERVE_SIZE
|
|
|
|
#else
|
|
# define TEXT 0x0
|
|
# define DATA
|
|
#endif
|
|
|
|
#if defined(CONFIG_LIBC_ARCH_ELF_64BIT)
|
|
# define SECTIONS_ALIGN 8
|
|
#else
|
|
# define SECTIONS_ALIGN 4
|
|
#endif
|
|
|
|
/* An FDPIC module is a shared object whose read-only and writable segments
|
|
* the loader places independently: the read-only one runs where the
|
|
* filesystem already holds it and only the writable one is copied to RAM,
|
|
* once per running instance. So the two go into segments of their own, and
|
|
* .dynamic is named, because a shared object is bound through it.
|
|
*
|
|
* Everything else is common, the symbols crt0.c walks included, so a module
|
|
* is built and entered the same way whichever this is.
|
|
*/
|
|
|
|
#ifdef CONFIG_FDPIC
|
|
# define PHDR_TEXT :text
|
|
# define PHDR_DATA :data
|
|
# define DATA_ALIGN . = ALIGN(0x1000);
|
|
|
|
PHDRS
|
|
{
|
|
text PT_LOAD FLAGS(5); /* Read and execute */
|
|
data PT_LOAD FLAGS(6); /* Read and write */
|
|
dynamic PT_DYNAMIC FLAGS(6);
|
|
}
|
|
|
|
#else
|
|
# define PHDR_TEXT
|
|
# define PHDR_DATA
|
|
# define DATA_ALIGN
|
|
#endif
|
|
|
|
SECTIONS
|
|
{
|
|
.text TEXT :
|
|
{
|
|
_stext = . ;
|
|
*(.text)
|
|
*(.text.*)
|
|
*(.gnu.warning)
|
|
*(.stub)
|
|
*(.glue_7)
|
|
*(.glue_7t)
|
|
*(.jcr)
|
|
. = ALIGN(SECTIONS_ALIGN);
|
|
_etext = . ;
|
|
} PHDR_TEXT
|
|
|
|
.rodata :
|
|
{
|
|
_srodata = . ;
|
|
*(.rodata)
|
|
*(.rodata1)
|
|
*(.rodata.*)
|
|
*(.gnu.linkonce.r*)
|
|
. = ALIGN(SECTIONS_ALIGN);
|
|
_erodata = . ;
|
|
} PHDR_TEXT
|
|
|
|
DATA_ALIGN
|
|
|
|
.data DATA :
|
|
{
|
|
_sdata = . ;
|
|
*(.data)
|
|
*(.data1)
|
|
*(.data.*)
|
|
*(.gnu.linkonce.d*)
|
|
. = ALIGN(SECTIONS_ALIGN);
|
|
_edata = . ;
|
|
} PHDR_DATA
|
|
|
|
.init_array :
|
|
{
|
|
_sinit = .;
|
|
_sctors = .;
|
|
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
|
KEEP(*(.init_array .ctors))
|
|
. = ALIGN(SECTIONS_ALIGN);
|
|
_einit = .;
|
|
_ectors = .;
|
|
} PHDR_DATA
|
|
|
|
.fini_array :
|
|
{
|
|
_sfini = .;
|
|
_sdtors = .;
|
|
KEEP (*(.dtors))
|
|
KEEP (*(.fini_array))
|
|
KEEP (*(SORT(.fini_array.*)))
|
|
. = ALIGN(SECTIONS_ALIGN);
|
|
_efini = .;
|
|
_edtors = .;
|
|
} PHDR_DATA
|
|
|
|
#ifdef CONFIG_FDPIC
|
|
.dynamic :
|
|
{
|
|
*(.dynamic)
|
|
} :data :dynamic
|
|
#endif
|
|
|
|
.got :
|
|
{
|
|
*(.got*)
|
|
} PHDR_DATA
|
|
|
|
/* .bss holds no file content, so it comes last. Everything ahead of it
|
|
* has content, thus the writable segment's p_filesz stops where .bss
|
|
* starts and the file does not carry it.
|
|
*/
|
|
|
|
.bss :
|
|
{
|
|
_sbss = . ;
|
|
*(.bss)
|
|
*(.bss.*)
|
|
*(.sbss)
|
|
*(.sbss.*)
|
|
*(.gnu.linkonce.b*)
|
|
*(COMMON)
|
|
. = ALIGN(SECTIONS_ALIGN);
|
|
_ebss = . ;
|
|
} PHDR_DATA
|
|
|
|
/* Stabs debugging sections. */
|
|
|
|
.stab 0 : { *(.stab) }
|
|
.stabstr 0 : { *(.stabstr) }
|
|
.stab.excl 0 : { *(.stab.excl) }
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }
|
|
.stab.index 0 : { *(.stab.index) }
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }
|
|
.comment 0 : { *(.comment) }
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
|
.debug_info 0 : { *(.debug_info) }
|
|
.debug_line 0 : { *(.debug_line) }
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
|
.debug_aranges 0 : { *(.debug_aranges) }
|
|
}
|