Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/eld/Diagnostics/DiagLDScript.inc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ DIAG(error_memory_region_exceeded_limit, DiagnosticEngine::Error,
"0x%2 bytes")
DIAG(error_memory_region_empty, DiagnosticEngine::Error,
"Missing name for memory region, name cannot be empty")
DIAG(error_section_not_in_region, DiagnosticEngine::Error,
"address 0x%2 of section '%0' is not within region '%1' (%3)")
DIAG(error_duplicate_memory_region, DiagnosticEngine::Error,
"Duplicate memory region %0")
DIAG(verbose_verified_add_memory_region, DiagnosticEngine::Verbose,
Expand Down
2 changes: 1 addition & 1 deletion include/eld/Object/ScriptMemoryRegion.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ScriptMemoryRegion {

void addOutputSectionLMA(const OutputSectionEntry *O);

void verifyMemoryUsage(LinkerConfig &Config);
void verifyMemoryUsage(LinkerConfig &Config, const OutputSectionEntry &out);

eld::Expected<uint64_t> getOrigin() const;

Expand Down
10 changes: 9 additions & 1 deletion lib/Object/ScriptMemoryRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,16 @@ void ScriptMemoryRegion::addOutputSection(const OutputSectionEntry *O) {
FirstOutputSectionExceededLimit = O;
}
}
void ScriptMemoryRegion::verifyMemoryUsage(LinkerConfig &Config,
const OutputSectionEntry &out) {
if (!out.prolog().hasVMA())
return;
uint64_t vma = out.prolog().vma().result();
if (!containsVMA(vma))
Config.raise(Diag::error_section_not_in_region)
<< out.name() << getName() << utility::toHex(vma)
<< out.prolog().vma().getContext();

void ScriptMemoryRegion::verifyMemoryUsage(LinkerConfig &Config) {
auto ExpLen = getLength();
if (ExpLen && !ExpLen.value() && Config.showLinkerScriptWarnings()) {
MemorySpec *Spec = MMemoryDesc->getMemorySpec();
Expand Down
7 changes: 5 additions & 2 deletions lib/Target/GNULDBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4970,8 +4970,11 @@ void GNULDBackend::clearMemoryRegions() {
}

void GNULDBackend::verifyMemoryRegions() {
for (auto &M : m_Module.getLinkerScript().getMemoryRegions())
M->verifyMemoryUsage(config());
for (auto *out : m_Module.getLinkerScript().sectionMap()) {
if (!out->epilog().hasRegion())
continue;
out->epilog().region().verifyMemoryUsage(config(), *out);
}
}

bool GNULDBackend::assignMemoryRegions() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
int foo() { return 1; }
int bar() { return 3; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
MEMORY {
RAM : ORIGIN = 0x1000, LENGTH = 0x1000
ROM : ORIGIN = 0x5000, LENGTH = 0x1000
}
SECTIONS {
.foo (0x2500) : { *(.text.foo) } >RAM
.bar : { *(.text.bar) } >RAM
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#---MemoryRegionVMACheck.test----------------------- Executable -----------------#
#BEGIN_COMMENT
# Test that ELD errors when a section VMA does not fit in its assigned
# memory region, matching BFD and LLD behavior.
#END_COMMENT
#START_TEST
RUN: %clang %clangg0opts -o %t1.1.o %p/Inputs/1.c -c -ffunction-sections
RUN: %not %link %linkopts -o %t1.1.out %t1.1.o -T %p/Inputs/script.t 2>&1 | %filecheck %s
#END_TEST
CHECK: address {{0x[0-9a-f]+}} of section '.foo' is not within region 'RAM'