2016-02-11 21:17:59 +00:00
|
|
|
//===- LinkerScript.h -------------------------------------------*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 08:50:56 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-02-11 21:17:59 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLD_ELF_LINKER_SCRIPT_H
|
|
|
|
#define LLD_ELF_LINKER_SCRIPT_H
|
|
|
|
|
2016-09-16 20:21:55 +00:00
|
|
|
#include "Config.h"
|
Reland: [LLD] Implement --enable-non-contiguous-regions (#90007)
When enabled, input sections that would otherwise overflow a memory
region are instead spilled to the next matching output section.
This feature parallels the one in GNU LD, but there are some differences
from its documented behavior:
- /DISCARD/ only matches previously-unmatched sections (i.e., the flag
does not affect it).
- If a section fails to fit at any of its matches, the link fails
instead of discarding the section.
- The flag --enable-non-contiguous-regions-warnings is not implemented,
as it exists to warn about such occurrences.
The implementation places stubs at possible spill locations, and
replaces them with the original input section when effecting spills.
Spilling decisions occur after address assignment. Sections are spilled
in reverse order of assignment, with each spill naively decreasing the
size of the affected memory regions. This continues until the memory
regions are brought back under size. Spilling anything causes another
pass of address assignment, and this continues to fixed point.
Spilling after rather than during assignment allows the algorithm to
consider the size effects of unspillable input sections that appear
later in the assignment. Otherwise, such sections (e.g. thunks) may
force an overflow, even if spilling something earlier could have avoided
it.
A few notable feature interactions occur:
- Stubs affect alignment, ONLY_IF_RO, etc, broadly as if a copy of the
input section were actually placed there.
- SHF_MERGE synthetic sections use the spill list of their first
contained input section (the one that gives the section its name).
- ICF occurs oblivious to spill sections; spill lists for merged-away
sections become inert and are removed after assignment.
- SHF_LINK_ORDER and .ARM.exidx are ordered according to the final
section ordering, after all spilling has completed.
- INSERT BEFORE/AFTER and OVERWRITE_SECTIONS are explicitly disallowed.
2024-05-13 12:30:50 -05:00
|
|
|
#include "InputSection.h"
|
2016-07-19 09:25:43 +00:00
|
|
|
#include "Writer.h"
|
2017-10-02 21:00:41 +00:00
|
|
|
#include "lld/Common/LLVM.h"
|
2018-02-28 17:38:19 +00:00
|
|
|
#include "lld/Common/Strings.h"
|
2016-11-05 01:00:56 +00:00
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
2017-01-24 02:34:00 +00:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2017-11-03 11:57:01 +00:00
|
|
|
#include "llvm/ADT/MapVector.h"
|
2024-03-25 16:11:21 -07:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2016-11-05 01:00:56 +00:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2022-10-02 13:23:52 -07:00
|
|
|
#include "llvm/Support/Compiler.h"
|
2016-11-05 01:00:56 +00:00
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdint>
|
2016-11-05 22:37:59 +00:00
|
|
|
#include <functional>
|
2016-11-05 01:00:56 +00:00
|
|
|
#include <memory>
|
2016-02-11 21:17:59 +00:00
|
|
|
|
2022-08-10 15:31:58 -04:00
|
|
|
namespace lld::elf {
|
2016-11-05 01:00:56 +00:00
|
|
|
|
2017-11-06 04:35:31 +00:00
|
|
|
class Defined;
|
2020-09-09 10:48:21 +01:00
|
|
|
class InputFile;
|
2017-02-23 16:49:07 +00:00
|
|
|
class InputSection;
|
2017-02-23 02:32:18 +00:00
|
|
|
class InputSectionBase;
|
2018-10-23 22:37:14 +00:00
|
|
|
class OutputSection;
|
2017-03-10 00:47:33 +00:00
|
|
|
class SectionBase;
|
2018-10-23 22:37:14 +00:00
|
|
|
class ThunkSection;
|
2022-03-08 11:23:41 -08:00
|
|
|
struct OutputDesc;
|
2024-08-05 13:06:45 -07:00
|
|
|
struct SectionClass;
|
|
|
|
struct SectionClassDesc;
|
2016-02-11 21:17:59 +00:00
|
|
|
|
2017-10-11 00:01:49 +00:00
|
|
|
// This represents an r-value in the linker script.
|
2017-03-17 13:05:04 +00:00
|
|
|
struct ExprValue {
|
2017-05-30 03:18:28 +00:00
|
|
|
ExprValue(SectionBase *sec, bool forceAbsolute, uint64_t val,
|
2017-06-07 08:54:43 +00:00
|
|
|
const Twine &loc)
|
2021-11-25 16:55:06 -08:00
|
|
|
: sec(sec), val(val), forceAbsolute(forceAbsolute), loc(loc.str()) {}
|
2017-10-11 00:01:49 +00:00
|
|
|
|
|
|
|
ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {}
|
|
|
|
|
2017-03-17 13:05:04 +00:00
|
|
|
bool isAbsolute() const { return forceAbsolute || sec == nullptr; }
|
|
|
|
uint64_t getValue() const;
|
2017-03-17 14:55:36 +00:00
|
|
|
uint64_t getSecAddr() const;
|
2017-09-12 00:06:00 +00:00
|
|
|
uint64_t getSectionOffset() const;
|
2017-10-11 00:01:49 +00:00
|
|
|
|
|
|
|
// If a value is relative to a section, it has a non-null Sec.
|
|
|
|
SectionBase *sec;
|
|
|
|
|
|
|
|
uint64_t val;
|
|
|
|
uint64_t alignment = 1;
|
|
|
|
|
2020-08-20 16:05:27 -07:00
|
|
|
// The original st_type if the expression represents a symbol. Any operation
|
|
|
|
// resets type to STT_NOTYPE.
|
|
|
|
uint8_t type = llvm::ELF::STT_NOTYPE;
|
|
|
|
|
2021-11-25 16:55:06 -08:00
|
|
|
// True if this expression is enclosed in ABSOLUTE().
|
|
|
|
// This flag affects the return value of getValue().
|
|
|
|
bool forceAbsolute;
|
|
|
|
|
2017-10-11 00:01:49 +00:00
|
|
|
// Original source location. Used for error messages.
|
|
|
|
std::string loc;
|
2017-03-17 13:05:04 +00:00
|
|
|
};
|
|
|
|
|
2016-10-13 23:08:33 +00:00
|
|
|
// This represents an expression in the linker script.
|
|
|
|
// ScriptParser::readExpr reads an expression and returns an Expr.
|
2017-03-17 13:05:04 +00:00
|
|
|
// Later, we evaluate the expression by calling the function.
|
2019-04-01 00:11:24 +00:00
|
|
|
using Expr = std::function<ExprValue()>;
|
Make readExpr return an Expr object instead of a vector of tokens.
Previously, we handled an expression as a vector of tokens. In other
words, an expression was a vector of uncooked raw StringRefs.
When we need a value of an expression, we used ExprParser to run
the expression.
The separation was needed essentially because parse time is too
early to evaluate an expression. In order to evaluate an expression,
we need to finalize section sizes. Because linker script parsing
is done at very early stage of the linking process, we can't
evaluate expressions while parsing.
The above mechanism worked fairly well, but there were a few
drawbacks.
One thing is that we sometimes have to parse the same expression
more than once in order to find the end of the expression.
In some contexts, linker script expressions have no clear end marker.
So, we needed to recognize balanced expressions and ternary operators.
The other is poor error reporting. Since expressions are parsed
basically twice, and some information that is available at the first
stage is lost in the second stage, it was hard to print out
apprpriate error messages.
This patch fixes the issues with a new approach.
Now the expression parsing is integrated into ScriptParser.
ExprParser class is removed. Expressions are represented as lambdas
instead of vectors of tokens. Lambdas captures information they
need to run themselves when they are created.
In this way, ends of expressions are naturally detected, and
errors are handled in the usual way. This patch also reduces
the amount of code.
Differential Revision: https://reviews.llvm.org/D22728
llvm-svn: 276574
2016-07-24 18:19:40 +00:00
|
|
|
|
2016-07-21 14:26:59 +00:00
|
|
|
// This enum is used to implement linker script SECTIONS command.
|
|
|
|
// https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
|
|
|
|
enum SectionsCommandKind {
|
2016-09-26 19:22:50 +00:00
|
|
|
AssignmentKind, // . = expr or <sym> = expr
|
2016-07-21 14:26:59 +00:00
|
|
|
OutputSectionKind,
|
2016-08-04 09:29:31 +00:00
|
|
|
InputSectionKind,
|
2024-08-05 13:06:45 -07:00
|
|
|
ByteKind, // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr)
|
|
|
|
ClassKind, // CLASS(class_name)
|
2016-02-12 21:47:28 +00:00
|
|
|
};
|
|
|
|
|
2021-11-25 20:24:23 -08:00
|
|
|
struct SectionCommand {
|
|
|
|
SectionCommand(int k) : kind(k) {}
|
2016-07-21 06:43:01 +00:00
|
|
|
int kind;
|
|
|
|
};
|
2016-04-16 10:10:32 +00:00
|
|
|
|
2016-10-13 23:08:33 +00:00
|
|
|
// This represents ". = <expr>" or "<symbol> = <expr>".
|
2021-11-25 20:24:23 -08:00
|
|
|
struct SymbolAssignment : SectionCommand {
|
2023-09-09 14:46:51 -07:00
|
|
|
SymbolAssignment(StringRef name, Expr e, unsigned symOrder, std::string loc)
|
2021-11-25 20:24:23 -08:00
|
|
|
: SectionCommand(AssignmentKind), name(name), expression(e),
|
2023-09-09 14:46:51 -07:00
|
|
|
symOrder(symOrder), location(loc) {}
|
2016-11-05 01:00:56 +00:00
|
|
|
|
2021-11-25 20:24:23 -08:00
|
|
|
static bool classof(const SectionCommand *c) {
|
2017-10-11 02:20:00 +00:00
|
|
|
return c->kind == AssignmentKind;
|
|
|
|
}
|
2016-07-29 05:52:33 +00:00
|
|
|
|
|
|
|
// The LHS of an expression. Name is either a symbol name or ".".
|
2016-07-21 06:43:01 +00:00
|
|
|
StringRef name;
|
2017-11-06 04:35:31 +00:00
|
|
|
Defined *sym = nullptr;
|
2016-07-29 05:52:33 +00:00
|
|
|
|
|
|
|
// The RHS of an expression.
|
Make readExpr return an Expr object instead of a vector of tokens.
Previously, we handled an expression as a vector of tokens. In other
words, an expression was a vector of uncooked raw StringRefs.
When we need a value of an expression, we used ExprParser to run
the expression.
The separation was needed essentially because parse time is too
early to evaluate an expression. In order to evaluate an expression,
we need to finalize section sizes. Because linker script parsing
is done at very early stage of the linking process, we can't
evaluate expressions while parsing.
The above mechanism worked fairly well, but there were a few
drawbacks.
One thing is that we sometimes have to parse the same expression
more than once in order to find the end of the expression.
In some contexts, linker script expressions have no clear end marker.
So, we needed to recognize balanced expressions and ternary operators.
The other is poor error reporting. Since expressions are parsed
basically twice, and some information that is available at the first
stage is lost in the second stage, it was hard to print out
apprpriate error messages.
This patch fixes the issues with a new approach.
Now the expression parsing is integrated into ScriptParser.
ExprParser class is removed. Expressions are represented as lambdas
instead of vectors of tokens. Lambdas captures information they
need to run themselves when they are created.
In this way, ends of expressions are naturally detected, and
errors are handled in the usual way. This patch also reduces
the amount of code.
Differential Revision: https://reviews.llvm.org/D22728
llvm-svn: 276574
2016-07-24 18:19:40 +00:00
|
|
|
Expr expression;
|
2016-07-29 05:52:33 +00:00
|
|
|
|
|
|
|
// Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
|
2016-07-22 07:38:40 +00:00
|
|
|
bool provide = false;
|
|
|
|
bool hidden = false;
|
2017-02-21 14:50:38 +00:00
|
|
|
|
[ELF] Align the end of PT_GNU_RELRO associated PT_LOAD to a common-page-size boundary (#66042)
Close #57618: currently we align the end of PT_GNU_RELRO to a
common-page-size
boundary, but do not align the end of the associated PT_LOAD. This is
benign
when runtime_page_size >= common-page-size.
However, when runtime_page_size < common-page-size, it is possible that
`alignUp(end(PT_LOAD), page_size) < alignDown(end(PT_GNU_RELRO),
page_size)`.
In this case, rtld's mprotect call for PT_GNU_RELRO will apply to
unmapped
regions and lead to an error, e.g.
```
error while loading shared libraries: cannot apply additional memory protection after relocation: Cannot allocate memory
```
To fix the issue, add a padding section .relro_padding like mold, which
is contained in the PT_GNU_RELRO segment and the associated PT_LOAD
segment. The section also prevents strip from corrupting PT_LOAD program
headers.
.relro_padding has the largest `sortRank` among RELRO sections.
Therefore, it is naturally placed at the end of `PT_GNU_RELRO` segment
in the absence of `PHDRS`/`SECTIONS` commands.
In the presence of `SECTIONS` commands, we place .relro_padding
immediately before a symbol assignment using DATA_SEGMENT_RELRO_END (see
also https://reviews.llvm.org/D124656), if present.
DATA_SEGMENT_RELRO_END is changed to align to max-page-size instead of
common-page-size.
Some edge cases worth mentioning:
* ppc64-toc-addis-nop.s: when PHDRS is present, do not append
.relro_padding
* avoid-empty-program-headers.s: when the only RELRO section is .tbss,
it is not part of PT_LOAD segment, therefore we do not append
.relro_padding.
---
Close #65002: GNU ld from 2.39 onwards aligns the end of PT_GNU_RELRO to
a
max-page-size boundary (https://sourceware.org/PR28824) so that the last
page is
protected even if runtime_page_size > common-page-size.
In my opinion, losing protection for the last page when the runtime page
size is
larger than common-page-size is not really an issue. Double mapping a
page of up
to max-common-page for the protection could cause undesired VM waste.
Internally
we had users complaining about 2MiB max-page-size applying to shared
objects.
Therefore, the end of .relro_padding is padded to a common-page-size
boundary. Users who are really anxious can set common-page-size to match
their runtime page size.
---
17 tests need updating as there are lots of change detectors.
2023-09-14 10:33:11 -07:00
|
|
|
// This assignment references DATA_SEGMENT_RELRO_END.
|
|
|
|
bool dataSegmentRelroEnd = false;
|
|
|
|
|
2023-09-09 14:46:51 -07:00
|
|
|
unsigned symOrder;
|
|
|
|
|
2017-02-22 09:13:04 +00:00
|
|
|
// Holds file name and line number for error reporting.
|
2017-02-21 14:50:38 +00:00
|
|
|
std::string location;
|
2018-03-15 09:16:40 +00:00
|
|
|
|
|
|
|
// A string representation of this command. We use this for -Map.
|
|
|
|
std::string commandString;
|
|
|
|
|
2018-04-04 09:39:05 +00:00
|
|
|
// Address of this assignment command.
|
2020-04-03 17:07:01 -07:00
|
|
|
uint64_t addr;
|
2018-03-15 09:16:40 +00:00
|
|
|
|
2018-04-04 09:39:05 +00:00
|
|
|
// Size of this assignment command. This is usually 0, but if
|
|
|
|
// you move '.' this may be greater than 0.
|
2020-04-03 17:07:01 -07:00
|
|
|
uint64_t size;
|
2016-07-21 06:43:01 +00:00
|
|
|
};
|
|
|
|
|
2019-10-28 21:41:38 -04:00
|
|
|
// Linker scripts allow additional constraints to be put on output sections.
|
2016-10-13 23:08:33 +00:00
|
|
|
// If an output section is marked as ONLY_IF_RO, the section is created
|
|
|
|
// only if its input sections are read-only. Likewise, an output section
|
|
|
|
// with ONLY_IF_RW is created if all input sections are RW.
|
2016-07-25 22:00:10 +00:00
|
|
|
enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
|
2016-07-22 03:36:24 +00:00
|
|
|
|
2017-04-06 21:31:24 +00:00
|
|
|
// This struct is used to represent the location and size of regions of
|
|
|
|
// target memory. Instances of the struct are created by parsing the
|
|
|
|
// MEMORY command.
|
|
|
|
struct MemoryRegion {
|
2020-03-06 11:49:58 -08:00
|
|
|
MemoryRegion(StringRef name, Expr origin, Expr length, uint32_t flags,
|
2021-11-24 12:17:03 +07:00
|
|
|
uint32_t invFlags, uint32_t negFlags, uint32_t negInvFlags)
|
2020-01-28 20:23:46 +01:00
|
|
|
: name(std::string(name)), origin(origin), length(length), flags(flags),
|
2021-11-24 12:17:03 +07:00
|
|
|
invFlags(invFlags), negFlags(negFlags), negInvFlags(negInvFlags) {}
|
[Coding style change] Rename variables so that they start with a lowercase letter
This patch is mechanically generated by clang-llvm-rename tool that I wrote
using Clang Refactoring Engine just for creating this patch. You can see the
source code of the tool at https://reviews.llvm.org/D64123. There's no manual
post-processing; you can generate the same patch by re-running the tool against
lld's code base.
Here is the main discussion thread to change the LLVM coding style:
https://lists.llvm.org/pipermail/llvm-dev/2019-February/130083.html
In the discussion thread, I proposed we use lld as a testbed for variable
naming scheme change, and this patch does that.
I chose to rename variables so that they are in camelCase, just because that
is a minimal change to make variables to start with a lowercase letter.
Note to downstream patch maintainers: if you are maintaining a downstream lld
repo, just rebasing ahead of this commit would cause massive merge conflicts
because this patch essentially changes every line in the lld subdirectory. But
there's a remedy.
clang-llvm-rename tool is a batch tool, so you can rename variables in your
downstream repo with the tool. Given that, here is how to rebase your repo to
a commit after the mass renaming:
1. rebase to the commit just before the mass variable renaming,
2. apply the tool to your downstream repo to mass-rename variables locally, and
3. rebase again to the head.
Most changes made by the tool should be identical for a downstream repo and
for the head, so at the step 3, almost all changes should be merged and
disappear. I'd expect that there would be some lines that you need to merge by
hand, but that shouldn't be too many.
Differential Revision: https://reviews.llvm.org/D64121
llvm-svn: 365595
2019-07-10 05:00:37 +00:00
|
|
|
|
2017-04-06 21:31:24 +00:00
|
|
|
std::string name;
|
2020-03-06 11:49:58 -08:00
|
|
|
Expr origin;
|
|
|
|
Expr length;
|
2021-11-24 12:17:03 +07:00
|
|
|
// A section can be assigned to the region if any of these ELF section flags
|
|
|
|
// are set...
|
2017-04-06 21:31:24 +00:00
|
|
|
uint32_t flags;
|
2021-11-24 12:17:03 +07:00
|
|
|
// ... or any of these flags are not set.
|
|
|
|
// For example, the memory region attribute "r" maps to SHF_WRITE.
|
|
|
|
uint32_t invFlags;
|
|
|
|
// A section cannot be assigned to the region if any of these ELF section
|
|
|
|
// flags are set...
|
2017-04-06 21:31:24 +00:00
|
|
|
uint32_t negFlags;
|
2021-11-24 12:17:03 +07:00
|
|
|
// ... or any of these flags are not set.
|
|
|
|
// For example, the memory region attribute "!r" maps to SHF_WRITE.
|
|
|
|
uint32_t negInvFlags;
|
2018-01-25 02:18:00 +00:00
|
|
|
uint64_t curPos = 0;
|
2021-11-24 12:17:03 +07:00
|
|
|
|
2023-05-16 07:18:26 +00:00
|
|
|
uint64_t getOrigin() const { return origin().getValue(); }
|
|
|
|
uint64_t getLength() const { return length().getValue(); }
|
|
|
|
|
2021-11-24 12:17:03 +07:00
|
|
|
bool compatibleWith(uint32_t secFlags) const {
|
|
|
|
if ((secFlags & negFlags) || (~secFlags & negInvFlags))
|
|
|
|
return false;
|
|
|
|
return (secFlags & flags) || (~secFlags & invFlags);
|
|
|
|
}
|
2017-04-06 21:31:24 +00:00
|
|
|
};
|
|
|
|
|
2016-09-17 07:31:49 +00:00
|
|
|
// This struct represents one section match pattern in SECTIONS() command.
|
2016-09-17 02:23:40 +00:00
|
|
|
// It can optionally have negative match pattern for EXCLUDED_FILE command.
|
2016-09-21 15:56:44 +00:00
|
|
|
// Also it may be surrounded with SORT() command, so contains sorting rules.
|
2020-09-09 10:48:21 +01:00
|
|
|
class SectionPattern {
|
|
|
|
StringMatcher excludedFilePat;
|
|
|
|
|
|
|
|
// Cache of the most recent input argument and result of excludesFile().
|
2022-11-26 19:19:15 -08:00
|
|
|
mutable std::optional<std::pair<const InputFile *, bool>> excludesFileCache;
|
2020-09-09 10:48:21 +01:00
|
|
|
|
|
|
|
public:
|
2016-11-03 17:57:38 +00:00
|
|
|
SectionPattern(StringMatcher &&pat1, StringMatcher &&pat2)
|
2018-12-06 08:34:52 +00:00
|
|
|
: excludedFilePat(pat1), sectionPat(pat2),
|
|
|
|
sortOuter(SortSectionPolicy::Default),
|
|
|
|
sortInner(SortSectionPolicy::Default) {}
|
[Coding style change] Rename variables so that they start with a lowercase letter
This patch is mechanically generated by clang-llvm-rename tool that I wrote
using Clang Refactoring Engine just for creating this patch. You can see the
source code of the tool at https://reviews.llvm.org/D64123. There's no manual
post-processing; you can generate the same patch by re-running the tool against
lld's code base.
Here is the main discussion thread to change the LLVM coding style:
https://lists.llvm.org/pipermail/llvm-dev/2019-February/130083.html
In the discussion thread, I proposed we use lld as a testbed for variable
naming scheme change, and this patch does that.
I chose to rename variables so that they are in camelCase, just because that
is a minimal change to make variables to start with a lowercase letter.
Note to downstream patch maintainers: if you are maintaining a downstream lld
repo, just rebasing ahead of this commit would cause massive merge conflicts
because this patch essentially changes every line in the lld subdirectory. But
there's a remedy.
clang-llvm-rename tool is a batch tool, so you can rename variables in your
downstream repo with the tool. Given that, here is how to rebase your repo to
a commit after the mass renaming:
1. rebase to the commit just before the mass variable renaming,
2. apply the tool to your downstream repo to mass-rename variables locally, and
3. rebase again to the head.
Most changes made by the tool should be identical for a downstream repo and
for the head, so at the step 3, almost all changes should be merged and
disappear. I'd expect that there would be some lines that you need to merge by
hand, but that shouldn't be too many.
Differential Revision: https://reviews.llvm.org/D64121
llvm-svn: 365595
2019-07-10 05:00:37 +00:00
|
|
|
|
2024-12-16 22:17:18 -08:00
|
|
|
bool excludesFile(const InputFile &file) const;
|
2020-09-09 10:48:21 +01:00
|
|
|
|
2016-11-03 17:57:38 +00:00
|
|
|
StringMatcher sectionPat;
|
2016-09-21 15:56:44 +00:00
|
|
|
SortSectionPolicy sortOuter;
|
|
|
|
SortSectionPolicy sortInner;
|
2016-09-17 02:23:40 +00:00
|
|
|
};
|
|
|
|
|
2021-11-25 20:24:23 -08:00
|
|
|
class InputSectionDescription : public SectionCommand {
|
2025-01-10 19:30:38 -08:00
|
|
|
enum class MatchType { Trivial, WholeArchive, ArchivesExcluded } matchType;
|
2020-09-09 10:48:21 +01:00
|
|
|
SingleStringMatcher filePat;
|
|
|
|
|
|
|
|
// Cache of the most recent input argument and result of matchesFile().
|
2022-11-26 19:19:15 -08:00
|
|
|
mutable std::optional<std::pair<const InputFile *, bool>> matchesFileCache;
|
2020-09-09 10:48:21 +01:00
|
|
|
|
|
|
|
public:
|
2020-01-15 09:38:00 +00:00
|
|
|
InputSectionDescription(StringRef filePattern, uint64_t withFlags = 0,
|
2024-08-05 13:06:45 -07:00
|
|
|
uint64_t withoutFlags = 0, StringRef classRef = {})
|
2025-01-10 19:30:38 -08:00
|
|
|
: SectionCommand(InputSectionKind), matchType(MatchType::Trivial),
|
|
|
|
filePat(filePattern), classRef(classRef), withFlags(withFlags),
|
|
|
|
withoutFlags(withoutFlags) {
|
2024-08-05 13:06:45 -07:00
|
|
|
assert((filePattern.empty() || classRef.empty()) &&
|
|
|
|
"file pattern and class reference are mutually exclusive");
|
2025-01-10 19:30:38 -08:00
|
|
|
|
|
|
|
// The matching syntax for whole archives and files outside of an archive
|
|
|
|
// can't be handled by SingleStringMatcher, and instead are handled
|
|
|
|
// manually within matchesFile()
|
|
|
|
if (!filePattern.empty()) {
|
|
|
|
if (filePattern.back() == ':') {
|
|
|
|
matchType = MatchType::WholeArchive;
|
|
|
|
filePat = filePattern.drop_back();
|
|
|
|
} else if (filePattern.front() == ':') {
|
|
|
|
matchType = MatchType::ArchivesExcluded;
|
|
|
|
filePat = filePattern.drop_front();
|
|
|
|
}
|
|
|
|
}
|
2024-08-05 13:06:45 -07:00
|
|
|
}
|
2016-11-05 01:00:56 +00:00
|
|
|
|
2021-11-25 20:24:23 -08:00
|
|
|
static bool classof(const SectionCommand *c) {
|
2017-10-11 02:20:00 +00:00
|
|
|
return c->kind == InputSectionKind;
|
|
|
|
}
|
2016-11-05 01:00:56 +00:00
|
|
|
|
2024-12-16 22:17:18 -08:00
|
|
|
bool matchesFile(const InputFile &file) const;
|
2016-09-17 02:23:40 +00:00
|
|
|
|
2016-09-17 07:31:49 +00:00
|
|
|
// Input sections that matches at least one of SectionPatterns
|
2016-09-17 02:34:50 +00:00
|
|
|
// will be associated with this InputSectionDescription.
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<SectionPattern, 0> sectionPatterns;
|
2016-09-17 02:23:40 +00:00
|
|
|
|
2024-08-05 13:06:45 -07:00
|
|
|
// If present, input section matching uses class membership instead of file
|
|
|
|
// and section patterns (mutually exclusive).
|
|
|
|
StringRef classRef;
|
|
|
|
|
2019-09-24 11:48:31 +00:00
|
|
|
// Includes InputSections and MergeInputSections. Used temporarily during
|
|
|
|
// assignment of input sections to output sections.
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<InputSectionBase *, 0> sectionBases;
|
2019-09-24 11:48:31 +00:00
|
|
|
|
|
|
|
// Used after the finalizeInputSections() pass. MergeInputSections have been
|
|
|
|
// merged into MergeSyntheticSections.
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<InputSection *, 0> sections;
|
2017-10-27 08:56:20 +00:00
|
|
|
|
2017-10-27 09:07:10 +00:00
|
|
|
// Temporary record of synthetic ThunkSection instances and the pass that
|
|
|
|
// they were created in. This is used to insert newly created ThunkSections
|
|
|
|
// into Sections at the end of a createThunks() pass.
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<std::pair<ThunkSection *, uint32_t>, 0> thunkSections;
|
2020-01-15 09:38:00 +00:00
|
|
|
|
|
|
|
// SectionPatterns can be filtered with the INPUT_SECTION_FLAGS command.
|
|
|
|
uint64_t withFlags;
|
|
|
|
uint64_t withoutFlags;
|
2016-07-21 14:26:59 +00:00
|
|
|
};
|
|
|
|
|
2016-10-13 23:08:33 +00:00
|
|
|
// Represents BYTE(), SHORT(), LONG(), or QUAD().
|
2021-11-25 20:24:23 -08:00
|
|
|
struct ByteCommand : SectionCommand {
|
2018-03-15 09:16:40 +00:00
|
|
|
ByteCommand(Expr e, unsigned size, std::string commandString)
|
2021-11-25 20:24:23 -08:00
|
|
|
: SectionCommand(ByteKind), commandString(commandString), expression(e),
|
2018-03-15 09:24:51 +00:00
|
|
|
size(size) {}
|
2016-11-05 01:00:56 +00:00
|
|
|
|
2021-11-25 20:24:23 -08:00
|
|
|
static bool classof(const SectionCommand *c) { return c->kind == ByteKind; }
|
2016-11-05 01:00:56 +00:00
|
|
|
|
2018-03-15 09:16:40 +00:00
|
|
|
// Keeps string representing the command. Used for -Map" is perhaps better.
|
|
|
|
std::string commandString;
|
|
|
|
|
2016-12-08 23:21:30 +00:00
|
|
|
Expr expression;
|
2018-04-04 09:39:05 +00:00
|
|
|
|
|
|
|
// This is just an offset of this assignment command in the output section.
|
2016-09-26 19:22:50 +00:00
|
|
|
unsigned offset;
|
2018-04-04 09:39:05 +00:00
|
|
|
|
|
|
|
// Size of this data command.
|
2016-09-26 19:22:50 +00:00
|
|
|
unsigned size;
|
|
|
|
};
|
|
|
|
|
2020-02-10 15:58:29 -08:00
|
|
|
struct InsertCommand {
|
2021-12-26 13:53:47 -08:00
|
|
|
SmallVector<StringRef, 0> names;
|
2020-02-10 15:58:29 -08:00
|
|
|
bool isAfter;
|
|
|
|
StringRef where;
|
|
|
|
};
|
|
|
|
|
2024-07-17 10:45:59 -07:00
|
|
|
// A NOCROSSREFS/NOCROSSREFS_TO command that prohibits references between
|
|
|
|
// certain output sections.
|
|
|
|
struct NoCrossRefCommand {
|
|
|
|
SmallVector<StringRef, 0> outputSections;
|
|
|
|
|
|
|
|
// When true, this describes a NOCROSSREFS_TO command that probits references
|
|
|
|
// to the first output section from any of the other sections.
|
|
|
|
bool toFirst = false;
|
|
|
|
};
|
|
|
|
|
2016-07-19 09:25:43 +00:00
|
|
|
struct PhdrsCommand {
|
|
|
|
StringRef name;
|
2017-10-08 03:45:49 +00:00
|
|
|
unsigned type = llvm::ELF::PT_NULL;
|
|
|
|
bool hasFilehdr = false;
|
|
|
|
bool hasPhdrs = false;
|
2022-11-26 19:19:15 -08:00
|
|
|
std::optional<unsigned> flags;
|
2017-10-08 03:45:49 +00:00
|
|
|
Expr lmaExpr = nullptr;
|
2016-04-16 10:10:32 +00:00
|
|
|
};
|
|
|
|
|
2017-05-10 14:45:15 +00:00
|
|
|
class LinkerScript final {
|
2017-10-11 02:28:28 +00:00
|
|
|
// Temporary state used in processSectionCommands() and assignAddresses()
|
2017-07-07 09:11:27 +00:00
|
|
|
// that must be reinitialized for each call to the above functions, and must
|
|
|
|
// not be used outside of the scope of a call to the above functions.
|
|
|
|
struct AddressState {
|
2024-09-21 10:22:11 -07:00
|
|
|
AddressState(const LinkerScript &);
|
2017-07-07 09:11:27 +00:00
|
|
|
OutputSection *outSec = nullptr;
|
|
|
|
MemoryRegion *memRegion = nullptr;
|
2018-01-25 17:42:03 +00:00
|
|
|
MemoryRegion *lmaRegion = nullptr;
|
2018-01-25 16:43:49 +00:00
|
|
|
uint64_t lmaOffset = 0;
|
2021-08-04 08:58:50 -07:00
|
|
|
uint64_t tbssAddr = 0;
|
2025-03-31 10:44:40 -07:00
|
|
|
uint64_t overlaySize;
|
2017-07-07 09:11:27 +00:00
|
|
|
};
|
2017-10-11 01:19:33 +00:00
|
|
|
|
2024-09-21 10:22:11 -07:00
|
|
|
Ctx &ctx;
|
2024-11-23 17:14:43 -08:00
|
|
|
SmallVector<std::unique_ptr<OutputDesc>, 0> descPool;
|
2022-03-08 11:23:41 -08:00
|
|
|
llvm::DenseMap<llvm::CachedHashStringRef, OutputDesc *> nameToOutputSection;
|
2017-06-01 01:16:50 +00:00
|
|
|
|
2024-08-21 20:27:44 -07:00
|
|
|
StringRef getOutputSectionName(const InputSectionBase *s) const;
|
2017-10-11 02:28:39 +00:00
|
|
|
void addSymbol(SymbolAssignment *cmd);
|
2024-10-06 19:36:21 -07:00
|
|
|
void declareSymbol(SymbolAssignment *cmd);
|
2017-04-05 03:20:22 +00:00
|
|
|
void assignSymbol(SymbolAssignment *cmd, bool inSec);
|
|
|
|
void setDot(Expr e, const Twine &loc, bool inSec);
|
2018-03-05 10:54:03 +00:00
|
|
|
void expandOutputSection(uint64_t size);
|
2018-03-26 08:58:16 +00:00
|
|
|
void expandMemoryRegions(uint64_t size);
|
2017-03-14 12:03:34 +00:00
|
|
|
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<InputSectionBase *, 0>
|
2020-05-08 13:19:12 +01:00
|
|
|
computeInputSections(const InputSectionDescription *,
|
2024-08-05 13:06:45 -07:00
|
|
|
ArrayRef<InputSectionBase *>, const SectionBase &outCmd);
|
2017-04-05 02:05:48 +00:00
|
|
|
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<InputSectionBase *, 0> createInputSectionList(OutputSection &cmd);
|
2017-03-14 12:03:34 +00:00
|
|
|
|
2020-05-08 13:19:12 +01:00
|
|
|
void discardSynthetic(OutputSection &);
|
|
|
|
|
2021-12-26 13:53:47 -08:00
|
|
|
SmallVector<size_t, 0> getPhdrIndices(OutputSection *sec);
|
2017-03-14 12:03:34 +00:00
|
|
|
|
2021-11-11 15:07:38 +07:00
|
|
|
std::pair<MemoryRegion *, MemoryRegion *>
|
|
|
|
findMemoryRegion(OutputSection *sec, MemoryRegion *hint);
|
2017-03-14 12:03:34 +00:00
|
|
|
|
2024-05-31 09:31:15 -07:00
|
|
|
bool assignOffsets(OutputSection *sec);
|
2017-10-18 12:09:41 +00:00
|
|
|
|
2022-10-01 15:27:39 -07:00
|
|
|
// This captures the local AddressState and makes it accessible
|
2017-10-23 21:12:19 +00:00
|
|
|
// deliberately. This is needed as there are some cases where we cannot just
|
|
|
|
// thread the current state through to a lambda function created by the
|
|
|
|
// script parser.
|
|
|
|
// This should remain a plain pointer as its lifetime is smaller than
|
|
|
|
// LinkerScript.
|
2022-10-01 15:27:39 -07:00
|
|
|
AddressState *state = nullptr;
|
2017-10-23 21:12:19 +00:00
|
|
|
|
2024-11-17 00:25:42 -08:00
|
|
|
std::unique_ptr<OutputSection> aether;
|
2017-03-14 09:03:53 +00:00
|
|
|
|
2024-08-21 21:12:18 -07:00
|
|
|
uint64_t dot = 0;
|
2017-03-14 12:03:34 +00:00
|
|
|
|
2017-03-14 09:03:53 +00:00
|
|
|
public:
|
2024-11-17 00:25:42 -08:00
|
|
|
// OutputSection may be incomplete. Avoid inline ctor/dtor.
|
|
|
|
LinkerScript(Ctx &ctx);
|
|
|
|
~LinkerScript();
|
|
|
|
|
2022-03-08 11:23:41 -08:00
|
|
|
OutputDesc *createOutputSection(StringRef name, StringRef location);
|
|
|
|
OutputDesc *getOrCreateOutputSection(StringRef name);
|
2017-06-01 01:16:50 +00:00
|
|
|
|
2017-10-11 01:19:33 +00:00
|
|
|
bool hasPhdrsCommands() { return !phdrsCommands.empty(); }
|
2017-03-16 21:50:30 +00:00
|
|
|
uint64_t getDot() { return dot; }
|
2021-12-22 20:51:11 -08:00
|
|
|
void discard(InputSectionBase &s);
|
2017-03-14 09:03:53 +00:00
|
|
|
|
2017-10-11 04:34:34 +00:00
|
|
|
ExprValue getSymbolValue(StringRef name, const Twine &loc);
|
2017-03-14 10:15:53 +00:00
|
|
|
|
2017-11-04 23:54:25 +00:00
|
|
|
void addOrphanSections();
|
2020-02-25 15:02:04 -08:00
|
|
|
void diagnoseOrphanHandling() const;
|
[LLD][ELF] Cortex-M Security Extensions (CMSE) Support
This commit provides linker support for Cortex-M Security Extensions (CMSE).
The specification for this feature can be found in ARM v8-M Security Extensions:
Requirements on Development Tools.
The linker synthesizes a security gateway veneer in a special section;
`.gnu.sgstubs`, when it finds non-local symbols `__acle_se_<entry>` and `<entry>`,
defined relative to the same text section and having the same address. The
address of `<entry>` is retargeted to the starting address of the
linker-synthesized security gateway veneer in section `.gnu.sgstubs`.
In summary, the linker translates input:
```
.text
entry:
__acle_se_entry:
[entry_code]
```
into:
```
.section .gnu.sgstubs
entry:
SG
B.W __acle_se_entry
.text
__acle_se_entry:
[entry_code]
```
If addresses of `__acle_se_<entry>` and `<entry>` are not equal, the linker
considers that `<entry>` already defines a secure gateway veneer so does not
synthesize one.
If `--out-implib=<out.lib>` is specified, the linker writes the list of secure
gateway veneers into a CMSE import library `<out.lib>`. The CMSE import library
will have 3 sections: `.symtab`, `.strtab`, `.shstrtab`. For every secure gateway
veneer <entry> at address `<addr>`, `.symtab` contains a `SHN_ABS` symbol `<entry>` with
value `<addr>`.
If `--in-implib=<in.lib>` is specified, the linker reads the existing CMSE import
library `<in.lib>` and preserves the entry function addresses in the resulting
executable and new import library.
Reviewed By: MaskRay, peter.smith
Differential Revision: https://reviews.llvm.org/D139092
2023-07-06 10:45:10 +01:00
|
|
|
void diagnoseMissingSGSectionAddress() const;
|
2022-02-01 10:16:12 -08:00
|
|
|
void adjustOutputSections();
|
2016-11-14 15:39:38 +00:00
|
|
|
void adjustSectionsAfterSorting();
|
2016-07-20 17:19:03 +00:00
|
|
|
|
2024-11-19 22:38:14 -08:00
|
|
|
SmallVector<std::unique_ptr<PhdrEntry>, 0> createPhdrs();
|
2017-10-08 03:52:15 +00:00
|
|
|
bool needsInterpSection();
|
2016-07-23 14:18:48 +00:00
|
|
|
|
2017-02-23 02:28:28 +00:00
|
|
|
bool shouldKeep(InputSectionBase *s);
|
2024-05-31 09:31:15 -07:00
|
|
|
std::pair<const OutputSection *, const Defined *> assignAddresses();
|
Reland: [LLD] Implement --enable-non-contiguous-regions (#90007)
When enabled, input sections that would otherwise overflow a memory
region are instead spilled to the next matching output section.
This feature parallels the one in GNU LD, but there are some differences
from its documented behavior:
- /DISCARD/ only matches previously-unmatched sections (i.e., the flag
does not affect it).
- If a section fails to fit at any of its matches, the link fails
instead of discarding the section.
- The flag --enable-non-contiguous-regions-warnings is not implemented,
as it exists to warn about such occurrences.
The implementation places stubs at possible spill locations, and
replaces them with the original input section when effecting spills.
Spilling decisions occur after address assignment. Sections are spilled
in reverse order of assignment, with each spill naively decreasing the
size of the affected memory regions. This continues until the memory
regions are brought back under size. Spilling anything causes another
pass of address assignment, and this continues to fixed point.
Spilling after rather than during assignment allows the algorithm to
consider the size effects of unspillable input sections that appear
later in the assignment. Otherwise, such sections (e.g. thunks) may
force an overflow, even if spilling something earlier could have avoided
it.
A few notable feature interactions occur:
- Stubs affect alignment, ONLY_IF_RO, etc, broadly as if a copy of the
input section were actually placed there.
- SHF_MERGE synthetic sections use the spill list of their first
contained input section (the one that gives the section its name).
- ICF occurs oblivious to spill sections; spill lists for merged-away
sections become inert and are removed after assignment.
- SHF_LINK_ORDER and .ARM.exidx are ordered according to the final
section ordering, after all spilling has completed.
- INSERT BEFORE/AFTER and OVERWRITE_SECTIONS are explicitly disallowed.
2024-05-13 12:30:50 -05:00
|
|
|
bool spillSections();
|
|
|
|
void erasePotentialSpillSections();
|
2024-11-19 22:38:14 -08:00
|
|
|
void allocateHeaders(SmallVector<std::unique_ptr<PhdrEntry>, 0> &phdrs);
|
2018-01-30 17:24:28 +00:00
|
|
|
void processSectionCommands();
|
2019-09-06 15:57:24 +00:00
|
|
|
void processSymbolAssignments();
|
2018-01-30 17:24:28 +00:00
|
|
|
void declareSymbols();
|
|
|
|
|
2018-03-08 14:54:38 +00:00
|
|
|
// Used to handle INSERT AFTER statements.
|
|
|
|
void processInsertCommands();
|
|
|
|
|
2023-05-16 07:18:26 +00:00
|
|
|
// Describe memory region usage.
|
|
|
|
void printMemoryUsage(raw_ostream &os);
|
|
|
|
|
2024-06-24 10:15:28 -07:00
|
|
|
// Record a pending error during an assignAddresses invocation.
|
|
|
|
// assignAddresses is executed more than once. Therefore, lld::error should be
|
|
|
|
// avoided to not report duplicate errors.
|
|
|
|
void recordError(const Twine &msg);
|
|
|
|
|
2023-09-20 09:06:45 -07:00
|
|
|
// Check backward location counter assignment and memory region/LMA overflows.
|
|
|
|
void checkFinalScriptConditions() const;
|
2023-06-14 15:26:31 -07:00
|
|
|
|
2024-03-25 16:11:21 -07:00
|
|
|
// Add symbols that are referenced in the linker script to the symbol table.
|
|
|
|
// Symbols referenced in a PROVIDE command are only added to the symbol table
|
|
|
|
// if the PROVIDE command actually provides the symbol.
|
|
|
|
// It also adds the symbols referenced by the used PROVIDE symbols to the
|
|
|
|
// linker script referenced symbols list.
|
|
|
|
void addScriptReferencedSymbolsToSymTable();
|
|
|
|
|
|
|
|
// Returns true if the PROVIDE symbol should be added to the link.
|
|
|
|
// A PROVIDE symbol is added to the link only if it satisfies an
|
|
|
|
// undefined reference.
|
2024-10-15 09:20:10 -07:00
|
|
|
bool shouldAddProvideSym(StringRef symName);
|
2024-03-25 16:11:21 -07:00
|
|
|
|
2018-01-30 17:24:28 +00:00
|
|
|
// SECTIONS command list.
|
2021-12-26 13:53:47 -08:00
|
|
|
SmallVector<SectionCommand *, 0> sectionCommands;
|
2017-10-11 01:19:33 +00:00
|
|
|
|
|
|
|
// PHDRS command list.
|
2021-12-26 13:53:47 -08:00
|
|
|
SmallVector<PhdrsCommand, 0> phdrsCommands;
|
2017-10-11 01:19:33 +00:00
|
|
|
|
2017-10-11 01:34:51 +00:00
|
|
|
bool hasSectionsCommand = false;
|
[ELF] Align the end of PT_GNU_RELRO associated PT_LOAD to a common-page-size boundary (#66042)
Close #57618: currently we align the end of PT_GNU_RELRO to a
common-page-size
boundary, but do not align the end of the associated PT_LOAD. This is
benign
when runtime_page_size >= common-page-size.
However, when runtime_page_size < common-page-size, it is possible that
`alignUp(end(PT_LOAD), page_size) < alignDown(end(PT_GNU_RELRO),
page_size)`.
In this case, rtld's mprotect call for PT_GNU_RELRO will apply to
unmapped
regions and lead to an error, e.g.
```
error while loading shared libraries: cannot apply additional memory protection after relocation: Cannot allocate memory
```
To fix the issue, add a padding section .relro_padding like mold, which
is contained in the PT_GNU_RELRO segment and the associated PT_LOAD
segment. The section also prevents strip from corrupting PT_LOAD program
headers.
.relro_padding has the largest `sortRank` among RELRO sections.
Therefore, it is naturally placed at the end of `PT_GNU_RELRO` segment
in the absence of `PHDRS`/`SECTIONS` commands.
In the presence of `SECTIONS` commands, we place .relro_padding
immediately before a symbol assignment using DATA_SEGMENT_RELRO_END (see
also https://reviews.llvm.org/D124656), if present.
DATA_SEGMENT_RELRO_END is changed to align to max-page-size instead of
common-page-size.
Some edge cases worth mentioning:
* ppc64-toc-addis-nop.s: when PHDRS is present, do not append
.relro_padding
* avoid-empty-program-headers.s: when the only RELRO section is .tbss,
it is not part of PT_LOAD segment, therefore we do not append
.relro_padding.
---
Close #65002: GNU ld from 2.39 onwards aligns the end of PT_GNU_RELRO to
a
max-page-size boundary (https://sourceware.org/PR28824) so that the last
page is
protected even if runtime_page_size > common-page-size.
In my opinion, losing protection for the last page when the runtime page
size is
larger than common-page-size is not really an issue. Double mapping a
page of up
to max-common-page for the protection could cause undesired VM waste.
Internally
we had users complaining about 2MiB max-page-size applying to shared
objects.
Therefore, the end of .relro_padding is padded to a common-page-size
boundary. Users who are really anxious can set common-page-size to match
their runtime page size.
---
17 tests need updating as there are lots of change detectors.
2023-09-14 10:33:11 -07:00
|
|
|
bool seenDataAlign = false;
|
|
|
|
bool seenRelroEnd = false;
|
2017-10-11 02:28:39 +00:00
|
|
|
bool errorOnMissingSection = false;
|
2024-06-24 10:15:28 -07:00
|
|
|
SmallVector<SmallString<0>, 0> recordedErrors;
|
2017-10-11 01:19:33 +00:00
|
|
|
|
|
|
|
// List of section patterns specified with KEEP commands. They will
|
|
|
|
// be kept even if they are unused and --gc-sections is specified.
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<InputSectionDescription *, 0> keptSections;
|
2017-10-11 01:19:33 +00:00
|
|
|
|
|
|
|
// A map from memory region name to a memory region descriptor.
|
2017-11-03 08:21:51 +00:00
|
|
|
llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions;
|
2017-10-11 01:19:33 +00:00
|
|
|
|
|
|
|
// A list of symbols referenced by the script.
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<llvm::StringRef, 0> referencedSymbols;
|
2018-03-08 14:54:38 +00:00
|
|
|
|
2020-02-10 15:58:29 -08:00
|
|
|
// Used to implement INSERT [AFTER|BEFORE]. Contains output sections that need
|
|
|
|
// to be reordered.
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<InsertCommand, 0> insertCommands;
|
2020-02-17 13:56:01 -08:00
|
|
|
|
2021-06-13 12:41:11 -07:00
|
|
|
// OutputSections specified by OVERWRITE_SECTIONS.
|
2022-03-08 11:23:41 -08:00
|
|
|
SmallVector<OutputDesc *, 0> overwriteSections;
|
2021-06-13 12:41:11 -07:00
|
|
|
|
2024-07-17 10:45:59 -07:00
|
|
|
// NOCROSSREFS(_TO) commands.
|
|
|
|
SmallVector<NoCrossRefCommand, 0> noCrossRefs;
|
|
|
|
|
2020-02-25 15:02:04 -08:00
|
|
|
// Sections that will be warned/errored by --orphan-handling.
|
2021-12-26 13:06:54 -08:00
|
|
|
SmallVector<const InputSectionBase *, 0> orphanSections;
|
2024-03-25 16:11:21 -07:00
|
|
|
|
|
|
|
// Stores the mapping: PROVIDE symbol -> symbols referred in the PROVIDE
|
|
|
|
// expression. For example, if the PROVIDE command is:
|
|
|
|
//
|
|
|
|
// PROVIDE(v = a + b + c);
|
|
|
|
//
|
|
|
|
// then provideMap should contain the mapping: 'v' -> ['a', 'b', 'c']
|
|
|
|
llvm::MapVector<StringRef, SmallVector<StringRef, 0>> provideMap;
|
2024-10-15 09:20:10 -07:00
|
|
|
// Store defined symbols that should ignore PROVIDE commands.
|
|
|
|
llvm::DenseSet<Symbol *> unusedProvideSyms;
|
Reland: [LLD] Implement --enable-non-contiguous-regions (#90007)
When enabled, input sections that would otherwise overflow a memory
region are instead spilled to the next matching output section.
This feature parallels the one in GNU LD, but there are some differences
from its documented behavior:
- /DISCARD/ only matches previously-unmatched sections (i.e., the flag
does not affect it).
- If a section fails to fit at any of its matches, the link fails
instead of discarding the section.
- The flag --enable-non-contiguous-regions-warnings is not implemented,
as it exists to warn about such occurrences.
The implementation places stubs at possible spill locations, and
replaces them with the original input section when effecting spills.
Spilling decisions occur after address assignment. Sections are spilled
in reverse order of assignment, with each spill naively decreasing the
size of the affected memory regions. This continues until the memory
regions are brought back under size. Spilling anything causes another
pass of address assignment, and this continues to fixed point.
Spilling after rather than during assignment allows the algorithm to
consider the size effects of unspillable input sections that appear
later in the assignment. Otherwise, such sections (e.g. thunks) may
force an overflow, even if spilling something earlier could have avoided
it.
A few notable feature interactions occur:
- Stubs affect alignment, ONLY_IF_RO, etc, broadly as if a copy of the
input section were actually placed there.
- SHF_MERGE synthetic sections use the spill list of their first
contained input section (the one that gives the section its name).
- ICF occurs oblivious to spill sections; spill lists for merged-away
sections become inert and are removed after assignment.
- SHF_LINK_ORDER and .ARM.exidx are ordered according to the final
section ordering, after all spilling has completed.
- INSERT BEFORE/AFTER and OVERWRITE_SECTIONS are explicitly disallowed.
2024-05-13 12:30:50 -05:00
|
|
|
|
|
|
|
// List of potential spill locations (PotentialSpillSection) for an input
|
|
|
|
// section.
|
|
|
|
struct PotentialSpillList {
|
|
|
|
// Never nullptr.
|
|
|
|
PotentialSpillSection *head;
|
|
|
|
PotentialSpillSection *tail;
|
|
|
|
};
|
|
|
|
llvm::DenseMap<InputSectionBase *, PotentialSpillList> potentialSpillLists;
|
2024-08-05 13:06:45 -07:00
|
|
|
|
|
|
|
// Named lists of input sections that can be collectively referenced in output
|
|
|
|
// section descriptions. Multiple references allow for sections to spill from
|
|
|
|
// one output section to another.
|
|
|
|
llvm::DenseMap<llvm::CachedHashStringRef, SectionClassDesc *> sectionClasses;
|
2016-04-20 20:13:41 +00:00
|
|
|
};
|
|
|
|
|
2022-08-10 15:31:58 -04:00
|
|
|
} // end namespace lld::elf
|
2016-02-11 21:17:59 +00:00
|
|
|
|
2016-11-05 01:00:56 +00:00
|
|
|
#endif // LLD_ELF_LINKER_SCRIPT_H
|