Skip to content

Commit 23fed03

Browse files
committed
Fix SUBALIGN linker script feature
This commit fixes the SUBALIGN linker script feature. SUBALIGN feature is used to modify the alignment of all input sections present in an output section. Until now, we were only changing the alignment of the first fragment of each rule of the output sections with SUBALIGN specified. This commit fixes the SUBALIGN behavior. SUBALIGN affects the alignment of the first fragment as is seen by the linker when traversing the output sections for the input sections that may contain more than 1 fragment such as .eh_frame, PLT / GOT sections, and .comment section. Resolves #343 Signed-off-by: Parth Arora <partaror@qti.qualcomm.com>
1 parent b996ed4 commit 23fed03

4 files changed

Lines changed: 52 additions & 2 deletions

File tree

include/eld/Object/ObjectLinker.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ class ObjectLinker {
312312

313313
bool initializeOutputSectionsAndRunPlugin();
314314

315+
void applySubAlign();
316+
315317
// Get Plugin list for Relocation registration callback.
316318
LinkerScript::PluginVectorT getLinkerPluginWithLinkerConfigs();
317319

lib/Object/ObjectLinker.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#include <chrono>
8181
#include <mutex>
8282
#include <sstream>
83+
#include <unordered_set>
8384

8485
using namespace llvm;
8586
using namespace eld;
@@ -1248,6 +1249,9 @@ bool ObjectLinker::mergeSections() {
12481249
{
12491250
eld::RegisterTimer T("Create Output Section", "Merge Sections",
12501251
ThisConfig.options().printTimingStats());
1252+
// Prepass: apply SUBALIGN to first fragments per input section per output
1253+
// section serially to avoid races in parallel output creation.
1254+
applySubAlign();
12511255
std::vector<OutputSectionEntry *> OutSections;
12521256
for (Out = OutBegin; Out != OutEnd; ++Out) {
12531257
OutSections.push_back(*Out);
@@ -1291,6 +1295,33 @@ bool ObjectLinker::initializeOutputSectionsAndRunPlugin() {
12911295
return runOutputSectionIteratorPlugin();
12921296
}
12931297

1298+
void ObjectLinker::applySubAlign() {
1299+
std::unordered_set<ELFSection *> seen;
1300+
1301+
for (auto *O : ThisModule->getScript().sectionMap()) {
1302+
auto &Prolog = O->prolog();
1303+
std::optional<uint64_t> optSubAlign;
1304+
if (Prolog.hasSubAlign()) {
1305+
Prolog.subAlign().eval();
1306+
Prolog.subAlign().commit();
1307+
optSubAlign = Prolog.subAlign().result();
1308+
}
1309+
1310+
for (RuleContainer *R : *O) {
1311+
ELFSection *InSect = R->getSection();
1312+
for (Fragment *F : InSect->getFragmentList()) {
1313+
ELFSection *owningSect = F->getOwningSection();
1314+
if (owningSect && seen.insert(owningSect).second && optSubAlign) {
1315+
F->setAlignment(optSubAlign.value());
1316+
InSect->setAddrAlign(
1317+
std::max(static_cast<uint64_t>(InSect->getAddrAlign()),
1318+
optSubAlign.value()));
1319+
}
1320+
}
1321+
}
1322+
}
1323+
}
1324+
12941325
void ObjectLinker::assignOffset(OutputSectionEntry *Out) {
12951326
int64_t O = 0;
12961327
const ELFSection *OutSection = Out->getSection();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
PHDRS {
2+
A PT_LOAD;
3+
}
4+
5+
SECTIONS {
6+
.a : SUBALIGN(64) {
7+
. = . + 1;
8+
*(.text*)
9+
}:A
10+
.b : SUBALIGN(64) {
11+
. = . + 1;
12+
}:A
13+
/DISCARD/ : { *(.ARM.exidx*) }
14+
}

test/Common/standalone/SubAlign/SubAlign.test

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
#END_COMMENT
55
#START_TEST
66
RUN: %clang %clangopts -c %p/Inputs/1.c -o %t1.1.o -ffunction-sections
7-
RUN: %link -MapStyle txt %linkopts %t1.1.o -T %p/Inputs/script.t -o %t1.1.o -Map %t2.map
8-
RUN: %filecheck %s < %t2.map
7+
RUN: %link -MapStyle txt %linkopts %t1.1.o -T %p/Inputs/script.t -o %t1.1.out -Map %t1.1.map.txt
8+
RUN: %filecheck %s < %t1.1.map.txt
9+
RUN: %link -MapStyle txt %linkopts %t1.1.o -T %p/Inputs/script.2.t -o %t1.2.out -Map %t1.2.map.txt
10+
RUN: %filecheck %s < %t1.1.map.txt
11+
RUN: %filecheck %s < %t1.2.map.txt
912
#CHECK: .a {{.*}} Alignment: 0x40
1013
#CHECK: .text.foo 0x40
1114
#CHECK: .text.bar 0x80

0 commit comments

Comments
 (0)