Skip to content

Commit d922832

Browse files
parth-07quic-seaswara
authored andcommitted
Fix dot counter handling for non-alloc sections
Until now, we were not properly handling dot counter in non-alloc sections and this was leading to incorrect symbol assignment evaluations in non-alloc sections, incorrect layout and non-alloc sections size incorrectly being set to 0. This commit fixes the dot counter handling in non-alloc sections. Now dot counter is moved around as usual in non-alloc sections but is restored to its original value after performing symbol evaluations and updating the output section size. Closes #91 Signed-off-by: Parth Arora <[email protected]>
1 parent cd6cfd9 commit d922832

File tree

5 files changed

+60
-5
lines changed

5 files changed

+60
-5
lines changed

lib/Target/GNULDBackend.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,6 +1909,7 @@ void GNULDBackend::evaluateAssignments(OutputSectionEntry *out,
19091909

19101910
// Initial dot symbol value.
19111911
dotSymbol->setValue(OutSection->addr());
1912+
LDSymbol::ValueType InitialDotValue = OutSection->addr();
19121913

19131914
if (m_Module.getPrinter()->traceAssignments())
19141915
config().raise(Diag::trace_output_section_addr)
@@ -2041,10 +2042,8 @@ void GNULDBackend::evaluateAssignments(OutputSectionEntry *out,
20412042
if (fillExpression)
20422043
getModule().setFragmentPaddingValue(F, fillExpression->result());
20432044
offset = F->getOffset(config().getDiagEngine()) + F->size();
2044-
if (OutSection->isAlloc()) {
2045-
dotSymbol->setValue(OutSection->addr() + offset);
2046-
offset = dotSymbol->value() - OutSection->addr();
2047-
}
2045+
dotSymbol->setValue(OutSection->addr() + offset);
2046+
offset = dotSymbol->value() - OutSection->addr();
20482047
++Begin;
20492048
}
20502049
RuleContainer *NextRule =
@@ -2053,7 +2052,7 @@ void GNULDBackend::evaluateAssignments(OutputSectionEntry *out,
20532052
if (InsertAtSectionToEnd(OutSection, offset, CurRule, NextRule,
20542053
fillExpression, atIndex))
20552054
atIndex++;
2056-
else if (OutSection->isAlloc())
2055+
else
20572056
dotSymbol->setValue(OutSection->addr() + offset);
20582057
}
20592058
CurRule->getSection()->setSize(offset);
@@ -2073,6 +2072,11 @@ void GNULDBackend::evaluateAssignments(OutputSectionEntry *out,
20732072
dotSymbol->setValue(OutSection->addr() + OutSection->size());
20742073
}
20752074

2075+
// Restore dot-value if OutSection is non-alloc section.
2076+
// dot counter (VMA) should not change in a non-alloc section.
2077+
if (!OutSection->isAlloc())
2078+
dotSymbol->setValue(InitialDotValue);
2079+
20762080
if (!(m_Module.getPrinter()->traceAssignments()))
20772081
return;
20782082

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
int foo() { return 1; }
2+
int bar() { return 3; }
3+
int baz() { return 5; }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
SECTIONS {
2+
.foo : { *(*foo*) }
3+
. = . + 0x100;
4+
my_start = .;
5+
.debug_info : {
6+
start = .;
7+
(.debug_info)
8+
end = . ;
9+
}
10+
my_end = .;
11+
mytext : { *(*text*) }
12+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
SECTIONS {
2+
.foo : { *(*foo*) }
3+
debug_info : {
4+
start = .;
5+
*(.debug_info*)
6+
end = .;
7+
}
8+
TEXT : { *(*text*) }
9+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#---NonAllocSectionSymbolAssignment.test--------------------------- Executable,LS --------------------#
2+
#BEGIN_COMMENT
3+
# This test checks that the linker properly evaluates symbol assignments in
4+
# non-alloc sections and that the layout is correct when non-alloc sections
5+
# contain symbol assignments.
6+
#END_COMMENT
7+
#START_TEST
8+
RUN: %clang %clangopts -o %t1.1.o %p/Inputs/1.c -c -ffunction-sections -g
9+
RUN: %link %linkopts -o %t1.1.out %t1.1.o -T %p/Inputs/script.t
10+
RUN: (%readelf -sS %t1.1.out && %readelf -S %t1.1.out) | %filecheck %s -check-prefix=READELF1
11+
12+
RUN: %link %linkopts -o %t1.1.2.out %t1.1.o -T %p/Inputs/script.2.t
13+
RUN: %readelf -sS %t1.1.2.out | %filecheck %s -check-prefix=READELF2
14+
15+
READELF1: .foo PROGBITS [[#%x,FOO_ADDRESS:]] [[#%x,FOO_OFFSET:]] [[#%x,FOO_SIZE:]] {{.*}} AX 0 0 [[#%u,FOO_ALIGNMENT:]]
16+
READELF1: debug_info PROGBITS {{[a-z0-9]+}} {{[a-z0-9]+}} [[#%x,DEBUG_INFO_SIZE:]]
17+
READELF1: TEXT PROGBITS {{0+}}[[#%x,FOO_ADDRESS+max(FOO_SIZE,FOO_ALIGNMENT)]] {{0+}}[[#%x,FOO_OFFSET+max(FOO_SIZE,FOO_ALIGNMENT)]] [[#%x,TEXTSIZE:]]
18+
READELF1: {{.*}}: [[#%x,START_VALUE:]] {{.*}} start
19+
READELF1: {{.*}}: {{0+}}[[#%x,START_VALUE+DEBUG_INFO_SIZE]] {{.*}} end
20+
READELF1: debug_info PROGBITS {{[a-z0-9]+}} {{0+}}[[#%x,FOO_OFFSET+max(FOO_SIZE,FOO_ALIGNMENT)+TEXTSIZE]]
21+
22+
READELF2: .foo PROGBITS [[#%x,FOO_ADDRESS:]] {{[a-z0-9]+}} [[#%x,FOO_SIZE:]] {{.*}} AX 0 0 [[#%u,FOO_ALIGNMENT:]]
23+
READELF2: mytext PROGBITS {{0+}}[[#%x,FOO_ADDRESS+max(FOO_SIZE,FOO_ALIGNMENT)+0x100]]
24+
READELF2-DAG: {{.*}}: {{0+}}[[#%x,MY_START_VALUE:FOO_ADDRESS+FOO_SIZE+0x100]] {{.*}} my_start
25+
READELF2-DAG: {{.*}}: {{0+}}[[#%x,MY_START_VALUE]] {{.*}} my_end
26+
27+
#END_TEST

0 commit comments

Comments
 (0)