diff --git a/include/eld/Diagnostics/DiagLDScript.inc b/include/eld/Diagnostics/DiagLDScript.inc index 47486cd08..5d40b10c5 100644 --- a/include/eld/Diagnostics/DiagLDScript.inc +++ b/include/eld/Diagnostics/DiagLDScript.inc @@ -75,6 +75,10 @@ DIAG(fatal_modulo_by_zero, DiagnosticEngine::Fatal, "%0: modulo by zero in expression %1") DIAG(error_experimental_not_supported, DiagnosticEngine::Error, "Linker has only experimental support for handling %0") +DIAG(error_negative_vma, DiagnosticEngine::Fatal, + "VMA is negative") +DIAG(error_negative_lma, DiagnosticEngine::Fatal, + "LMA is negative") DIAG(error_memory_region_exceeded_limit, DiagnosticEngine::Error, "Memory region %0 exceeded limit while adding section %1") DIAG(error_memory_region_empty, DiagnosticEngine::Error, diff --git a/lib/Target/CreateProgramHeaders.hpp b/lib/Target/CreateProgramHeaders.hpp index bdea0a907..3870b167f 100644 --- a/lib/Target/CreateProgramHeaders.hpp +++ b/lib/Target/CreateProgramHeaders.hpp @@ -251,6 +251,10 @@ bool GNULDBackend::createProgramHdrs() { // If the output section specified a VMA value. if ((*out)->prolog().hasVMA()) { (*out)->prolog().vma().evaluateAndRaiseError(); + if ((*out)->prolog().vma().isUnaryMinus()) { + config().raise(Diag::error_negative_vma); + return true; + } // If the output section descriptor has an alignment specified // honor the alignment specified, the alignment would have been // reflected in the section alignment. @@ -450,6 +454,10 @@ bool GNULDBackend::createProgramHdrs() { // Explicitly align LMA to make the code easy to read if (useSetLMA) { (*out)->prolog().lma().evaluateAndRaiseError(); + if ((*out)->prolog().lma().isUnaryMinus()) { + config().raise(Diag::error_negative_lma); + return true; + } pma = (*out)->prolog().lma().result(); } else if (hasVMARegion || hasLMARegion) { ScriptMemoryRegion &R = (*out)->epilog().lmaRegion(); diff --git a/test/Common/standalone/NegativeVMA_LMA/Inputs/1.c b/test/Common/standalone/NegativeVMA_LMA/Inputs/1.c new file mode 100644 index 000000000..b79e0f77b --- /dev/null +++ b/test/Common/standalone/NegativeVMA_LMA/Inputs/1.c @@ -0,0 +1 @@ +int foo() { return 1; } \ No newline at end of file diff --git a/test/Common/standalone/NegativeVMA_LMA/Inputs/script.t b/test/Common/standalone/NegativeVMA_LMA/Inputs/script.t new file mode 100644 index 000000000..ca768de73 --- /dev/null +++ b/test/Common/standalone/NegativeVMA_LMA/Inputs/script.t @@ -0,0 +1,3 @@ +SECTIONS { + .foo (-0x201) : AT(0x1000) { *(.text.foo) } +} \ No newline at end of file diff --git a/test/Common/standalone/NegativeVMA_LMA/Inputs/script_1.t b/test/Common/standalone/NegativeVMA_LMA/Inputs/script_1.t new file mode 100644 index 000000000..7e62eb77a --- /dev/null +++ b/test/Common/standalone/NegativeVMA_LMA/Inputs/script_1.t @@ -0,0 +1,3 @@ +SECTIONS { + .foo (0x201) : AT(-0x1000) { *(.text.foo) } +} diff --git a/test/Common/standalone/NegativeVMA_LMA/NegativeVMA_LMA.test b/test/Common/standalone/NegativeVMA_LMA/NegativeVMA_LMA.test new file mode 100644 index 000000000..fa757a2a5 --- /dev/null +++ b/test/Common/standalone/NegativeVMA_LMA/NegativeVMA_LMA.test @@ -0,0 +1,11 @@ +#--NegativeVMA_LMA.test------------------ Executable----------------# +#BEGIN_COMMENT +# Verify that the linker errors out when the VMA/LMA +# is negative. +#END_COMMENT +RUN: %clang %clangopts -c %p/Inputs/1.c -o %t1.1.o +RUN: %not %link %linkopts %t1.1.o -T %p/Inputs/script.t -o %t2_vma.out 2>&1 | %filecheck %s +RUN: %not %link %linkopts %t1.1.o -T %p/Inputs/script_1.t -o %t2_lma.out 2>&1 | %filecheck %s --check-prefix=LMA + +CHECK: VMA is negative +LMA: LMA is negative \ No newline at end of file