1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
|
//===- InputSection.cpp ---------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "InputSection.h"
#include "Config.h"
#include "InputFiles.h"
#include "OutputSections.h"
#include "Relocations.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/CommonLinkerContext.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/xxhash.h"
#include <algorithm>
#include <mutex>
#include <vector>
using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::support;
using namespace llvm::support::endian;
using namespace llvm::sys;
using namespace lld;
using namespace lld::elf;
DenseSet<std::pair<const Symbol *, uint64_t>> elf::ppc64noTocRelax;
// Returns a string to construct an error message.
std::string lld::toString(const InputSectionBase *sec) {
return (toString(sec->file) + ":(" + sec->name + ")").str();
}
template <class ELFT>
static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &file,
const typename ELFT::Shdr &hdr) {
if (hdr.sh_type == SHT_NOBITS)
return ArrayRef<uint8_t>(nullptr, hdr.sh_size);
return check(file.getObj().getSectionContents(hdr));
}
InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags,
uint32_t type, uint64_t entsize,
uint32_t link, uint32_t info,
uint32_t addralign, ArrayRef<uint8_t> data,
StringRef name, Kind sectionKind)
: SectionBase(sectionKind, name, flags, entsize, addralign, type, info,
link),
file(file), content_(data.data()), size(data.size()) {
// In order to reduce memory allocation, we assume that mergeable
// sections are smaller than 4 GiB, which is not an unreasonable
// assumption as of 2017.
if (sectionKind == SectionBase::Merge && content().size() > UINT32_MAX)
error(toString(this) + ": section too large");
// The ELF spec states that a value of 0 means the section has
// no alignment constraints.
uint32_t v = std::max<uint32_t>(addralign, 1);
if (!isPowerOf2_64(v))
fatal(toString(this) + ": sh_addralign is not a power of 2");
this->addralign = v;
// If SHF_COMPRESSED is set, parse the header. The legacy .zdebug format is no
// longer supported.
if (flags & SHF_COMPRESSED)
invokeELFT(parseCompressedHeader,);
}
// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
// SHF_GROUP is a marker that a section belongs to some comdat group.
// That flag doesn't make sense in an executable.
static uint64_t getFlags(uint64_t flags) {
flags &= ~(uint64_t)SHF_INFO_LINK;
if (!config->relocatable)
flags &= ~(uint64_t)SHF_GROUP;
return flags;
}
template <class ELFT>
InputSectionBase::InputSectionBase(ObjFile<ELFT> &file,
const typename ELFT::Shdr &hdr,
StringRef name, Kind sectionKind)
: InputSectionBase(&file, getFlags(hdr.sh_flags), hdr.sh_type,
hdr.sh_entsize, hdr.sh_link, hdr.sh_info,
hdr.sh_addralign, getSectionContents(file, hdr), name,
sectionKind) {
// We reject object files having insanely large alignments even though
// they are allowed by the spec. I think 4GB is a reasonable limitation.
// We might want to relax this in the future.
if (hdr.sh_addralign > UINT32_MAX)
fatal(toString(&file) + ": section sh_addralign is too large");
}
size_t InputSectionBase::getSize() const {
if (auto *s = dyn_cast<SyntheticSection>(this))
return s->getSize();
return size - bytesDropped;
}
template <class ELFT>
static void decompressAux(const InputSectionBase &sec, uint8_t *out,
size_t size) {
auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(sec.content_);
auto compressed = ArrayRef<uint8_t>(sec.content_, sec.compressedSize)
.slice(sizeof(typename ELFT::Chdr));
if (Error e = hdr->ch_type == ELFCOMPRESS_ZLIB
? compression::zlib::decompress(compressed, out, size)
: compression::zstd::decompress(compressed, out, size))
fatal(toString(&sec) +
": decompress failed: " + llvm::toString(std::move(e)));
}
void InputSectionBase::decompress() const {
uint8_t *uncompressedBuf;
{
static std::mutex mu;
std::lock_guard<std::mutex> lock(mu);
uncompressedBuf = bAlloc().Allocate<uint8_t>(size);
}
invokeELFT(decompressAux, *this, uncompressedBuf, size);
content_ = uncompressedBuf;
compressed = false;
}
template <class ELFT> RelsOrRelas<ELFT> InputSectionBase::relsOrRelas() const {
if (relSecIdx == 0)
return {};
RelsOrRelas<ELFT> ret;
typename ELFT::Shdr shdr =
cast<ELFFileBase>(file)->getELFShdrs<ELFT>()[relSecIdx];
if (shdr.sh_type == SHT_REL) {
ret.rels = ArrayRef(reinterpret_cast<const typename ELFT::Rel *>(
file->mb.getBufferStart() + shdr.sh_offset),
shdr.sh_size / sizeof(typename ELFT::Rel));
} else {
assert(shdr.sh_type == SHT_RELA);
ret.relas = ArrayRef(reinterpret_cast<const typename ELFT::Rela *>(
file->mb.getBufferStart() + shdr.sh_offset),
shdr.sh_size / sizeof(typename ELFT::Rela));
}
return ret;
}
uint64_t SectionBase::getOffset(uint64_t offset) const {
switch (kind()) {
case Output: {
auto *os = cast<OutputSection>(this);
// For output sections we treat offset -1 as the end of the section.
return offset == uint64_t(-1) ? os->size : offset;
}
case Regular:
case Synthetic:
return cast<InputSection>(this)->outSecOff + offset;
case EHFrame: {
// Two code paths may reach here. First, clang_rt.crtbegin.o and GCC
// crtbeginT.o may reference the start of an empty .eh_frame to identify the
// start of the output .eh_frame. Just return offset.
//
// Second, InputSection::copyRelocations on .eh_frame. Some pieces may be
// discarded due to GC/ICF. We should compute the output section offset.
const EhInputSection *es = cast<EhInputSection>(this);
if (!es->content().empty())
if (InputSection *isec = es->getParent())
return isec->outSecOff + es->getParentOffset(offset);
return offset;
}
case Merge:
const MergeInputSection *ms = cast<MergeInputSection>(this);
if (InputSection *isec = ms->getParent())
return isec->outSecOff + ms->getParentOffset(offset);
return ms->getParentOffset(offset);
}
llvm_unreachable("invalid section kind");
}
uint64_t SectionBase::getVA(uint64_t offset) const {
const OutputSection *out = getOutputSection();
return (out ? out->addr : 0) + getOffset(offset);
}
OutputSection *SectionBase::getOutputSection() {
InputSection *sec;
if (auto *isec = dyn_cast<InputSection>(this))
sec = isec;
else if (auto *ms = dyn_cast<MergeInputSection>(this))
sec = ms->getParent();
else if (auto *eh = dyn_cast<EhInputSection>(this))
sec = eh->getParent();
else
return cast<OutputSection>(this);
return sec ? sec->getParent() : nullptr;
}
// When a section is compressed, `rawData` consists with a header followed
// by zlib-compressed data. This function parses a header to initialize
// `uncompressedSize` member and remove the header from `rawData`.
template <typename ELFT> void InputSectionBase::parseCompressedHeader() {
flags &= ~(uint64_t)SHF_COMPRESSED;
// New-style header
if (content().size() < sizeof(typename ELFT::Chdr)) {
error(toString(this) + ": corrupted compressed section");
return;
}
auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(content().data());
if (hdr->ch_type == ELFCOMPRESS_ZLIB) {
if (!compression::zlib::isAvailable())
error(toString(this) + " is compressed with ELFCOMPRESS_ZLIB, but lld is "
"not built with zlib support");
} else if (hdr->ch_type == ELFCOMPRESS_ZSTD) {
if (!compression::zstd::isAvailable())
error(toString(this) + " is compressed with ELFCOMPRESS_ZSTD, but lld is "
"not built with zstd support");
} else {
error(toString(this) + ": unsupported compression type (" +
Twine(hdr->ch_type) + ")");
return;
}
compressed = true;
compressedSize = size;
size = hdr->ch_size;
addralign = std::max<uint32_t>(hdr->ch_addralign, 1);
}
InputSection *InputSectionBase::getLinkOrderDep() const {
assert(flags & SHF_LINK_ORDER);
if (!link)
return nullptr;
return cast<InputSection>(file->getSections()[link]);
}
// Find a symbol that encloses a given location.
Defined *InputSectionBase::getEnclosingSymbol(uint64_t offset,
uint8_t type) const {
for (Symbol *b : file->getSymbols())
if (Defined *d = dyn_cast<Defined>(b))
if (d->section == this && d->value <= offset &&
offset < d->value + d->size && (type == 0 || type == d->type))
return d;
return nullptr;
}
// Returns an object file location string. Used to construct an error message.
std::string InputSectionBase::getLocation(uint64_t offset) const {
std::string secAndOffset =
(name + "+0x" + Twine::utohexstr(offset) + ")").str();
// We don't have file for synthetic sections.
if (file == nullptr)
return (config->outputFile + ":(" + secAndOffset).str();
std::string filename = toString(file);
if (Defined *d = getEnclosingFunction(offset))
return filename + ":(function " + toString(*d) + ": " + secAndOffset;
return filename + ":(" + secAndOffset;
}
// This function is intended to be used for constructing an error message.
// The returned message looks like this:
//
// foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
//
// Returns an empty string if there's no way to get line info.
std::string InputSectionBase::getSrcMsg(const Symbol &sym,
uint64_t offset) const {
return file->getSrcMsg(sym, *this, offset);
}
// Returns a filename string along with an optional section name. This
// function is intended to be used for constructing an error
// message. The returned message looks like this:
//
// path/to/foo.o:(function bar)
//
// or
//
// path/to/foo.o:(function bar) in archive path/to/bar.a
std::string InputSectionBase::getObjMsg(uint64_t off) const {
std::string filename = std::string(file->getName());
std::string archive;
if (!file->archiveName.empty())
archive = (" in archive " + file->archiveName).str();
// Find a symbol that encloses a given location. getObjMsg may be called
// before ObjFile::initSectionsAndLocalSyms where local symbols are
// initialized.
if (Defined *d = getEnclosingSymbol(off))
return filename + ":(" + toString(*d) + ")" + archive;
// If there's no symbol, print out the offset in the section.
return (filename + ":(" + name + "+0x" + utohexstr(off) + ")" + archive)
.str();
}
InputSection InputSection::discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
InputSection::InputSection(InputFile *f, uint64_t flags, uint32_t type,
uint32_t addralign, ArrayRef<uint8_t> data,
StringRef name, Kind k)
: InputSectionBase(f, flags, type,
/*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, addralign, data,
name, k) {}
template <class ELFT>
InputSection::InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
StringRef name)
: InputSectionBase(f, header, name, InputSectionBase::Regular) {}
// Copy SHT_GROUP section contents. Used only for the -r option.
template <class ELFT> void InputSection::copyShtGroup(uint8_t *buf) {
// ELFT::Word is the 32-bit integral type in the target endianness.
using u32 = typename ELFT::Word;
ArrayRef<u32> from = getDataAs<u32>();
auto *to = reinterpret_cast<u32 *>(buf);
// The first entry is not a section number but a flag.
*to++ = from[0];
// Adjust section numbers because section numbers in an input object files are
// different in the output. We also need to handle combined or discarded
// members.
ArrayRef<InputSectionBase *> sections = file->getSections();
DenseSet<uint32_t> seen;
for (uint32_t idx : from.slice(1)) {
OutputSection *osec = sections[idx]->getOutputSection();
if (osec && seen.insert(osec->sectionIndex).second)
*to++ = osec->sectionIndex;
}
}
InputSectionBase *InputSection::getRelocatedSection() const {
if (!file || (type != SHT_RELA && type != SHT_REL))
return nullptr;
ArrayRef<InputSectionBase *> sections = file->getSections();
return sections[info];
}
template <class ELFT, class RelTy>
void InputSection::copyRelocations(uint8_t *buf) {
if (config->relax && !config->relocatable && config->emachine == EM_RISCV) {
// On RISC-V, relaxation might change relocations: copy from internal ones
// that are updated by relaxation.
InputSectionBase *sec = getRelocatedSection();
copyRelocations<ELFT, RelTy>(buf, llvm::make_range(sec->relocations.begin(),
sec->relocations.end()));
} else {
// Convert the raw relocations in the input section into Relocation objects
// suitable to be used by copyRelocations below.
struct MapRel {
const ObjFile<ELFT> &file;
Relocation operator()(const RelTy &rel) const {
// RelExpr is not used so set to a dummy value.
return Relocation{R_NONE, rel.getType(config->isMips64EL), rel.r_offset,
getAddend<ELFT>(rel), &file.getRelocTargetSym(rel)};
}
};
using RawRels = ArrayRef<RelTy>;
using MapRelIter =
llvm::mapped_iterator<typename RawRels::iterator, MapRel>;
auto mapRel = MapRel{*getFile<ELFT>()};
RawRels rawRels = getDataAs<RelTy>();
auto rels = llvm::make_range(MapRelIter(rawRels.begin(), mapRel),
MapRelIter(rawRels.end(), mapRel));
copyRelocations<ELFT, RelTy>(buf, rels);
}
}
// This is used for -r and --emit-relocs. We can't use memcpy to copy
// relocations because we need to update symbol table offset and section index
// for each relocation. So we copy relocations one by one.
template <class ELFT, class RelTy, class RelIt>
void InputSection::copyRelocations(uint8_t *buf,
llvm::iterator_range<RelIt> rels) {
const TargetInfo &target = *elf::target;
InputSectionBase *sec = getRelocatedSection();
(void)sec->contentMaybeDecompress(); // uncompress if needed
for (const Relocation &rel : rels) {
RelType type = rel.type;
const ObjFile<ELFT> *file = getFile<ELFT>();
Symbol &sym = *rel.sym;
auto *p = reinterpret_cast<typename ELFT::Rela *>(buf);
buf += sizeof(RelTy);
if (RelTy::IsRela)
p->r_addend = rel.addend;
// Output section VA is zero for -r, so r_offset is an offset within the
// section, but for --emit-relocs it is a virtual address.
p->r_offset = sec->getVA(rel.offset);
p->setSymbolAndType(in.symTab->getSymbolIndex(&sym), type,
config->isMips64EL);
if (sym.type == STT_SECTION) {
// We combine multiple section symbols into only one per
// section. This means we have to update the addend. That is
// trivial for Elf_Rela, but for Elf_Rel we have to write to the
// section data. We do that by adding to the Relocation vector.
// .eh_frame is horribly special and can reference discarded sections. To
// avoid having to parse and recreate .eh_frame, we just replace any
// relocation in it pointing to discarded sections with R_*_NONE, which
// hopefully creates a frame that is ignored at runtime. Also, don't warn
// on .gcc_except_table and debug sections.
//
// See the comment in maybeReportUndefined for PPC32 .got2 and PPC64 .toc
auto *d = dyn_cast<Defined>(&sym);
if (!d) {
if (!isDebugSection(*sec) && sec->name != ".eh_frame" &&
sec->name != ".gcc_except_table" && sec->name != ".got2" &&
sec->name != ".toc") {
uint32_t secIdx = cast<Undefined>(sym).discardedSecIdx;
Elf_Shdr_Impl<ELFT> sec = file->template getELFShdrs<ELFT>()[secIdx];
warn("relocation refers to a discarded section: " +
CHECK(file->getObj().getSectionName(sec), file) +
"\n>>> referenced by " + getObjMsg(p->r_offset));
}
p->setSymbolAndType(0, 0, false);
continue;
}
SectionBase *section = d->section;
assert(section->isLive());
int64_t addend = rel.addend;
const uint8_t *bufLoc = sec->content().begin() + rel.offset;
if (!RelTy::IsRela)
addend = target.getImplicitAddend(bufLoc, type);
if (config->emachine == EM_MIPS &&
target.getRelExpr(type, sym, bufLoc) == R_MIPS_GOTREL) {
// Some MIPS relocations depend on "gp" value. By default,
// this value has 0x7ff0 offset from a .got section. But
// relocatable files produced by a compiler or a linker
// might redefine this default value and we must use it
// for a calculation of the relocation result. When we
// generate EXE or DSO it's trivial. Generating a relocatable
// output is more difficult case because the linker does
// not calculate relocations in this mode and loses
// individual "gp" values used by each input object file.
// As a workaround we add the "gp" value to the relocation
// addend and save it back to the file.
addend += sec->getFile<ELFT>()->mipsGp0;
}
if (RelTy::IsRela)
p->r_addend = sym.getVA(addend) - section->getOutputSection()->addr;
// For SHF_ALLOC sections relocated by REL, append a relocation to
// sec->relocations so that relocateAlloc transitively called by
// writeSections will update the implicit addend. Non-SHF_ALLOC sections
// utilize relocateNonAlloc to process raw relocations and do not need
// this sec->relocations change.
else if (config->relocatable && (sec->flags & SHF_ALLOC) &&
type != target.noneRel)
sec->addReloc({R_ABS, type, rel.offset, addend, &sym});
} else if (config->emachine == EM_PPC && type == R_PPC_PLTREL24 &&
p->r_addend >= 0x8000 && sec->file->ppc32Got2) {
// Similar to R_MIPS_GPREL{16,32}. If the addend of R_PPC_PLTREL24
// indicates that r30 is relative to the input section .got2
// (r_addend>=0x8000), after linking, r30 should be relative to the output
// section .got2 . To compensate for the shift, adjust r_addend by
// ppc32Got->outSecOff.
p->r_addend += sec->file->ppc32Got2->outSecOff;
}
}
}
// The ARM and AArch64 ABI handle pc-relative relocations to undefined weak
// references specially. The general rule is that the value of the symbol in
// this context is the address of the place P. A further special case is that
// branch relocations to an undefined weak reference resolve to the next
// instruction.
static uint32_t getARMUndefinedRelativeWeakVA(RelType type, uint32_t a,
uint32_t p) {
switch (type) {
// Unresolved branch relocations to weak references resolve to next
// instruction, this will be either 2 or 4 bytes on from P.
case R_ARM_THM_JUMP8:
case R_ARM_THM_JUMP11:
return p + 2 + a;
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PC24:
case R_ARM_PLT32:
case R_ARM_PREL31:
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
return p + 4 + a;
case R_ARM_THM_CALL:
// We don't want an interworking BLX to ARM
return p + 5 + a;
// Unresolved non branch pc-relative relocations
// R_ARM_TARGET2 which can be resolved relatively is not present as it never
// targets a weak-reference.
case R_ARM_MOVW_PREL_NC:
case R_ARM_MOVT_PREL:
case R_ARM_REL32:
case R_ARM_THM_ALU_PREL_11_0:
case R_ARM_THM_MOVW_PREL_NC:
case R_ARM_THM_MOVT_PREL:
case R_ARM_THM_PC12:
return p + a;
// p + a is unrepresentable as negative immediates can't be encoded.
case R_ARM_THM_PC8:
return p;
}
llvm_unreachable("ARM pc-relative relocation expected\n");
}
// The comment above getARMUndefinedRelativeWeakVA applies to this function.
static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t type, uint64_t p) {
switch (type) {
// Unresolved branch relocations to weak references resolve to next
// instruction, this is 4 bytes on from P.
case R_AARCH64_CALL26:
case R_AARCH64_CONDBR19:
case R_AARCH64_JUMP26:
case R_AARCH64_TSTBR14:
return p + 4;
// Unresolved non branch pc-relative relocations
case R_AARCH64_PREL16:
case R_AARCH64_PREL32:
case R_AARCH64_PREL64:
case R_AARCH64_ADR_PREL_LO21:
case R_AARCH64_LD_PREL_LO19:
case R_AARCH64_PLT32:
return p;
}
llvm_unreachable("AArch64 pc-relative relocation expected\n");
}
static uint64_t getRISCVUndefinedRelativeWeakVA(uint64_t type, uint64_t p) {
switch (type) {
case R_RISCV_BRANCH:
case R_RISCV_JAL:
case R_RISCV_CALL:
case R_RISCV_CALL_PLT:
case R_RISCV_RVC_BRANCH:
case R_RISCV_RVC_JUMP:
case R_RISCV_PLT32:
return p;
default:
return 0;
}
}
// ARM SBREL relocations are of the form S + A - B where B is the static base
// The ARM ABI defines base to be "addressing origin of the output segment
// defining the symbol S". We defined the "addressing origin"/static base to be
// the base of the PT_LOAD segment containing the Sym.
// The procedure call standard only defines a Read Write Position Independent
// RWPI variant so in practice we should expect the static base to be the base
// of the RW segment.
static uint64_t getARMStaticBase(const Symbol &sym) {
OutputSection *os = sym.getOutputSection();
if (!os || !os->ptLoad || !os->ptLoad->firstSec)
fatal("SBREL relocation to " + sym.getName() + " without static base");
return os->ptLoad->firstSec->addr;
}
// For R_RISCV_PC_INDIRECT (R_RISCV_PCREL_LO12_{I,S}), the symbol actually
// points the corresponding R_RISCV_PCREL_HI20 relocation, and the target VA
// is calculated using PCREL_HI20's symbol.
//
// This function returns the R_RISCV_PCREL_HI20 relocation from
// R_RISCV_PCREL_LO12's symbol and addend.
static Relocation *getRISCVPCRelHi20(const Symbol *sym, uint64_t addend) {
const Defined *d = cast<Defined>(sym);
if (!d->section) {
errorOrWarn("R_RISCV_PCREL_LO12 relocation points to an absolute symbol: " +
sym->getName());
return nullptr;
}
InputSection *isec = cast<InputSection>(d->section);
if (addend != 0)
warn("non-zero addend in R_RISCV_PCREL_LO12 relocation to " +
isec->getObjMsg(d->value) + " is ignored");
// Relocations are sorted by offset, so we can use std::equal_range to do
// binary search.
Relocation r;
r.offset = d->value;
auto range =
std::equal_range(isec->relocs().begin(), isec->relocs().end(), r,
[](const Relocation &lhs, const Relocation &rhs) {
return lhs.offset < rhs.offset;
});
for (auto it = range.first; it != range.second; ++it)
if (it->type == R_RISCV_PCREL_HI20 || it->type == R_RISCV_GOT_HI20 ||
it->type == R_RISCV_TLS_GD_HI20 || it->type == R_RISCV_TLS_GOT_HI20)
return &*it;
errorOrWarn("R_RISCV_PCREL_LO12 relocation points to " +
isec->getObjMsg(d->value) +
" without an associated R_RISCV_PCREL_HI20 relocation");
return nullptr;
}
// A TLS symbol's virtual address is relative to the TLS segment. Add a
// target-specific adjustment to produce a thread-pointer-relative offset.
static int64_t getTlsTpOffset(const Symbol &s) {
// On targets that support TLSDESC, _TLS_MODULE_BASE_@tpoff = 0.
if (&s == ElfSym::tlsModuleBase)
return 0;
// There are 2 TLS layouts. Among targets we support, x86 uses TLS Variant 2
// while most others use Variant 1. At run time TP will be aligned to p_align.
// Variant 1. TP will be followed by an optional gap (which is the size of 2
// pointers on ARM/AArch64, 0 on other targets), followed by alignment
// padding, then the static TLS blocks. The alignment padding is added so that
// (TP + gap + padding) is congruent to p_vaddr modulo p_align.
//
// Variant 2. Static TLS blocks, followed by alignment padding are placed
// before TP. The alignment padding is added so that (TP - padding -
// p_memsz) is congruent to p_vaddr modulo p_align.
PhdrEntry *tls = Out::tlsPhdr;
switch (config->emachine) {
// Variant 1.
case EM_ARM:
case EM_AARCH64:
return s.getVA(0) + config->wordsize * 2 +
((tls->p_vaddr - config->wordsize * 2) & (tls->p_align - 1));
case EM_MIPS:
case EM_PPC:
case EM_PPC64:
// Adjusted Variant 1. TP is placed with a displacement of 0x7000, which is
// to allow a signed 16-bit offset to reach 0x1000 of TCB/thread-library
// data and 0xf000 of the program's TLS segment.
return s.getVA(0) + (tls->p_vaddr & (tls->p_align - 1)) - 0x7000;
case EM_LOONGARCH:
case EM_RISCV:
return s.getVA(0) + (tls->p_vaddr & (tls->p_align - 1));
// Variant 2.
case EM_HEXAGON:
case EM_SPARCV9:
case EM_386:
case EM_X86_64:
return s.getVA(0) - tls->p_memsz -
((-tls->p_vaddr - tls->p_memsz) & (tls->p_align - 1));
default:
llvm_unreachable("unhandled Config->EMachine");
}
}
uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
int64_t a, uint64_t p,
const Symbol &sym, RelExpr expr) {
switch (expr) {
case R_ABS:
case R_DTPREL:
case R_RELAX_TLS_LD_TO_LE_ABS:
case R_RELAX_GOT_PC_NOPIC:
case R_RISCV_ADD:
return sym.getVA(a);
case R_ADDEND:
return a;
case R_RELAX_HINT:
return 0;
case R_ARM_SBREL:
return sym.getVA(a) - getARMStaticBase(sym);
case R_GOT:
case R_RELAX_TLS_GD_TO_IE_ABS:
return sym.getGotVA() + a;
case R_LOONGARCH_GOT:
// The LoongArch TLS GD relocs reuse the R_LARCH_GOT_PC_LO12 reloc type
// for their page offsets. The arithmetics are different in the TLS case
// so we have to duplicate some logic here.
if (sym.hasFlag(NEEDS_TLSGD) && type != R_LARCH_TLS_IE_PC_LO12)
// Like R_LOONGARCH_TLSGD_PAGE_PC but taking the absolute value.
return in.got->getGlobalDynAddr(sym) + a;
return getRelocTargetVA(file, type, a, p, sym, R_GOT);
case R_GOTONLY_PC:
return in.got->getVA() + a - p;
case R_GOTPLTONLY_PC:
return in.gotPlt->getVA() + a - p;
case R_GOTREL:
case R_PPC64_RELAX_TOC:
return sym.getVA(a) - in.got->getVA();
case R_GOTPLTREL:
return sym.getVA(a) - in.gotPlt->getVA();
case R_GOTPLT:
case R_RELAX_TLS_GD_TO_IE_GOTPLT:
return sym.getGotVA() + a - in.gotPlt->getVA();
case R_TLSLD_GOT_OFF:
case R_GOT_OFF:
case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
return sym.getGotOffset() + a;
case R_AARCH64_GOT_PAGE_PC:
case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
return getAArch64Page(sym.getGotVA() + a) - getAArch64Page(p);
case R_AARCH64_GOT_PAGE:
return sym.getGotVA() + a - getAArch64Page(in.got->getVA());
case R_GOT_PC:
case R_RELAX_TLS_GD_TO_IE:
return sym.getGotVA() + a - p;
case R_LOONGARCH_GOT_PAGE_PC:
if (sym.hasFlag(NEEDS_TLSGD))
return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p);
return getLoongArchPageDelta(sym.getGotVA() + a, p);
case R_MIPS_GOTREL:
return sym.getVA(a) - in.mipsGot->getGp(file);
case R_MIPS_GOT_GP:
return in.mipsGot->getGp(file) + a;
case R_MIPS_GOT_GP_PC: {
// R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target
// is _gp_disp symbol. In that case we should use the following
// formula for calculation "AHL + GP - P + 4". For details see p. 4-19 at
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
// microMIPS variants of these relocations use slightly different
// expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi()
// to correctly handle less-significant bit of the microMIPS symbol.
uint64_t v = in.mipsGot->getGp(file) + a - p;
if (type == R_MIPS_LO16 || type == R_MICROMIPS_LO16)
v += 4;
if (type == R_MICROMIPS_LO16 || type == R_MICROMIPS_HI16)
v -= 1;
return v;
}
case R_MIPS_GOT_LOCAL_PAGE:
// If relocation against MIPS local symbol requires GOT entry, this entry
// should be initialized by 'page address'. This address is high 16-bits
// of sum the symbol's value and the addend.
return in.mipsGot->getVA() + in.mipsGot->getPageEntryOffset(file, sym, a) -
in.mipsGot->getGp(file);
case R_MIPS_GOT_OFF:
case R_MIPS_GOT_OFF32:
// In case of MIPS if a GOT relocation has non-zero addend this addend
// should be applied to the GOT entry content not to the GOT entry offset.
// That is why we use separate expression type.
return in.mipsGot->getVA() + in.mipsGot->getSymEntryOffset(file, sym, a) -
in.mipsGot->getGp(file);
case R_MIPS_TLSGD:
return in.mipsGot->getVA() + in.mipsGot->getGlobalDynOffset(file, sym) -
in.mipsGot->getGp(file);
case R_MIPS_TLSLD:
return in.mipsGot->getVA() + in.mipsGot->getTlsIndexOffset(file) -
in.mipsGot->getGp(file);
case R_AARCH64_PAGE_PC: {
uint64_t val = sym.isUndefWeak() ? p + a : sym.getVA(a);
return getAArch64Page(val) - getAArch64Page(p);
}
case R_RISCV_PC_INDIRECT: {
if (const Relocation *hiRel = getRISCVPCRelHi20(&sym, a))
return getRelocTargetVA(file, hiRel->type, hiRel->addend, sym.getVA(),
*hiRel->sym, hiRel->expr);
return 0;
}
case R_LOONGARCH_PAGE_PC:
return getLoongArchPageDelta(sym.getVA(a), p);
case R_PC:
case R_ARM_PCA: {
uint64_t dest;
if (expr == R_ARM_PCA)
// Some PC relative ARM (Thumb) relocations align down the place.
p = p & 0xfffffffc;
if (sym.isUndefined()) {
// On ARM and AArch64 a branch to an undefined weak resolves to the next
// instruction, otherwise the place. On RISC-V, resolve an undefined weak
// to the same instruction to cause an infinite loop (making the user
// aware of the issue) while ensuring no overflow.
// Note: if the symbol is hidden, its binding has been converted to local,
// so we just check isUndefined() here.
if (config->emachine == EM_ARM)
dest = getARMUndefinedRelativeWeakVA(type, a, p);
else if (config->emachine == EM_AARCH64)
dest = getAArch64UndefinedRelativeWeakVA(type, p) + a;
else if (config->emachine == EM_PPC)
dest = p;
else if (config->emachine == EM_RISCV)
dest = getRISCVUndefinedRelativeWeakVA(type, p) + a;
else
dest = sym.getVA(a);
} else {
dest = sym.getVA(a);
}
return dest - p;
}
case R_PLT:
return sym.getPltVA() + a;
case R_PLT_PC:
case R_PPC64_CALL_PLT:
return sym.getPltVA() + a - p;
case R_LOONGARCH_PLT_PAGE_PC:
return getLoongArchPageDelta(sym.getPltVA() + a, p);
case R_PLT_GOTPLT:
return sym.getPltVA() + a - in.gotPlt->getVA();
case R_PPC32_PLTREL:
// R_PPC_PLTREL24 uses the addend (usually 0 or 0x8000) to indicate r30
// stores _GLOBAL_OFFSET_TABLE_ or .got2+0x8000. The addend is ignored for
// target VA computation.
return sym.getPltVA() - p;
case R_PPC64_CALL: {
uint64_t symVA = sym.getVA(a);
// If we have an undefined weak symbol, we might get here with a symbol
// address of zero. That could overflow, but the code must be unreachable,
// so don't bother doing anything at all.
if (!symVA)
return 0;
// PPC64 V2 ABI describes two entry points to a function. The global entry
// point is used for calls where the caller and callee (may) have different
// TOC base pointers and r2 needs to be modified to hold the TOC base for
// the callee. For local calls the caller and callee share the same
// TOC base and so the TOC pointer initialization code should be skipped by
// branching to the local entry point.
return symVA - p + getPPC64GlobalEntryToLocalEntryOffset(sym.stOther);
}
case R_PPC64_TOCBASE:
return getPPC64TocBase() + a;
case R_RELAX_GOT_PC:
case R_PPC64_RELAX_GOT_PC:
return sym.getVA(a) - p;
case R_RELAX_TLS_GD_TO_LE:
case R_RELAX_TLS_IE_TO_LE:
case R_RELAX_TLS_LD_TO_LE:
case R_TPREL:
// It is not very clear what to return if the symbol is undefined. With
// --noinhibit-exec, even a non-weak undefined reference may reach here.
// Just return A, which matches R_ABS, and the behavior of some dynamic
// loaders.
if (sym.isUndefined())
return a;
return getTlsTpOffset(sym) + a;
case R_RELAX_TLS_GD_TO_LE_NEG:
case R_TPREL_NEG:
if (sym.isUndefined())
return a;
return -getTlsTpOffset(sym) + a;
case R_SIZE:
return sym.getSize() + a;
case R_TLSDESC:
return in.got->getTlsDescAddr(sym) + a;
case R_TLSDESC_PC:
return in.got->getTlsDescAddr(sym) + a - p;
case R_TLSDESC_GOTPLT:
return in.got->getTlsDescAddr(sym) + a - in.gotPlt->getVA();
case R_AARCH64_TLSDESC_PAGE:
return getAArch64Page(in.got->getTlsDescAddr(sym) + a) - getAArch64Page(p);
case R_TLSGD_GOT:
return in.got->getGlobalDynOffset(sym) + a;
case R_TLSGD_GOTPLT:
return in.got->getGlobalDynAddr(sym) + a - in.gotPlt->getVA();
case R_TLSGD_PC:
return in.got->getGlobalDynAddr(sym) + a - p;
case R_LOONGARCH_TLSGD_PAGE_PC:
return getLoongArchPageDelta(in.got->getGlobalDynAddr(sym) + a, p);
case R_TLSLD_GOTPLT:
return in.got->getVA() + in.got->getTlsIndexOff() + a - in.gotPlt->getVA();
case R_TLSLD_GOT:
return in.got->getTlsIndexOff() + a;
case R_TLSLD_PC:
return in.got->getTlsIndexVA() + a - p;
default:
llvm_unreachable("invalid expression");
}
}
// Overwrite a ULEB128 value and keep the original length.
static uint64_t overwriteULEB128(uint8_t *bufLoc, uint64_t val) {
while (*bufLoc & 0x80) {
*bufLoc++ = 0x80 | (val & 0x7f);
val >>= 7;
}
*bufLoc = val;
return val;
}
// This function applies relocations to sections without SHF_ALLOC bit.
// Such sections are never mapped to memory at runtime. Debug sections are
// an example. Relocations in non-alloc sections are much easier to
// handle than in allocated sections because it will never need complex
// treatment such as GOT or PLT (because at runtime no one refers them).
// So, we handle relocations for non-alloc sections directly in this
// function as a performance optimization.
template <class ELFT, class RelTy>
void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
const unsigned bits = sizeof(typename ELFT::uint) * 8;
const TargetInfo &target = *elf::target;
const auto emachine = config->emachine;
const bool isDebug = isDebugSection(*this);
const bool isDebugLocOrRanges =
isDebug && (name == ".debug_loc" || name == ".debug_ranges");
const bool isDebugLine = isDebug && name == ".debug_line";
std::optional<uint64_t> tombstone;
for (const auto &patAndValue : llvm::reverse(config->deadRelocInNonAlloc))
if (patAndValue.first.match(this->name)) {
tombstone = patAndValue.second;
break;
}
for (size_t i = 0, relsSize = rels.size(); i != relsSize; ++i) {
const RelTy &rel = rels[i];
RelType type = rel.getType(config->isMips64EL);
// GCC 8.0 or earlier have a bug that they emit R_386_GOTPC relocations
// against _GLOBAL_OFFSET_TABLE_ for .debug_info. The bug has been fixed
// in 2017 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630), but we
// need to keep this bug-compatible code for a while.
if (emachine == EM_386 && type == R_386_GOTPC)
continue;
uint64_t offset = rel.r_offset;
uint8_t *bufLoc = buf + offset;
int64_t addend = getAddend<ELFT>(rel);
if (!RelTy::IsRela)
addend += target.getImplicitAddend(bufLoc, type);
Symbol &sym = getFile<ELFT>()->getRelocTargetSym(rel);
RelExpr expr = target.getRelExpr(type, sym, bufLoc);
if (expr == R_NONE)
continue;
auto *ds = dyn_cast<Defined>(&sym);
if (emachine == EM_RISCV && type == R_RISCV_SET_ULEB128) {
if (++i < relsSize &&
rels[i].getType(/*isMips64EL=*/false) == R_RISCV_SUB_ULEB128 &&
rels[i].r_offset == offset) {
uint64_t val;
if (!ds && tombstone) {
val = *tombstone;
} else {
val = sym.getVA(addend) -
(getFile<ELFT>()->getRelocTargetSym(rels[i]).getVA(0) +
getAddend<ELFT>(rels[i]));
}
if (overwriteULEB128(bufLoc, val) >= 0x80)
errorOrWarn(getLocation(offset) + ": ULEB128 value " + Twine(val) +
" exceeds available space; references '" +
lld::toString(sym) + "'");
continue;
}
errorOrWarn(getLocation(offset) +
": R_RISCV_SET_ULEB128 not paired with R_RISCV_SUB_SET128");
return;
}
if (tombstone ||
(isDebug && (type == target.symbolicRel || expr == R_DTPREL))) {
// Resolve relocations in .debug_* referencing (discarded symbols or ICF
// folded section symbols) to a tombstone value. Resolving to addend is
// unsatisfactory because the result address range may collide with a
// valid range of low address, or leave multiple CUs claiming ownership of
// the same range of code, which may confuse consumers.
//
// To address the problems, we use -1 as a tombstone value for most
// .debug_* sections. We have to ignore the addend because we don't want
// to resolve an address attribute (which may have a non-zero addend) to
// -1+addend (wrap around to a low address).
//
// R_DTPREL type relocations represent an offset into the dynamic thread
// vector. The computed value is st_value plus a non-negative offset.
// Negative values are invalid, so -1 can be used as the tombstone value.
//
// If the referenced symbol is discarded (made Undefined), or the
// section defining the referenced symbol is garbage collected,
// sym.getOutputSection() is nullptr. `ds->folded` catches the ICF folded
// case. However, resolving a relocation in .debug_line to -1 would stop
// debugger users from setting breakpoints on the folded-in function, so
// exclude .debug_line.
//
// For pre-DWARF-v5 .debug_loc and .debug_ranges, -1 is a reserved value
// (base address selection entry), use 1 (which is used by GNU ld for
// .debug_ranges).
//
// TODO To reduce disruption, we use 0 instead of -1 as the tombstone
// value. Enable -1 in a future release.
if (!sym.getOutputSection() || (ds && ds->folded && !isDebugLine)) {
// If -z dead-reloc-in-nonalloc= is specified, respect it.
const uint64_t value = tombstone ? SignExtend64<bits>(*tombstone)
: (isDebugLocOrRanges ? 1 : 0);
target.relocateNoSym(bufLoc, type, value);
continue;
}
}
// For a relocatable link, content relocated by RELA remains unchanged and
// we can stop here, while content relocated by REL referencing STT_SECTION
// needs updating implicit addends.
if (config->relocatable && (RelTy::IsRela || sym.type != STT_SECTION))
continue;
if (expr == R_SIZE) {
target.relocateNoSym(bufLoc, type,
SignExtend64<bits>(sym.getSize() + addend));
continue;
}
// R_ABS/R_DTPREL and some other relocations can be used from non-SHF_ALLOC
// sections.
if (expr == R_ABS || expr == R_DTPREL || expr == R_GOTPLTREL ||
expr == R_RISCV_ADD) {
target.relocateNoSym(bufLoc, type, SignExtend64<bits>(sym.getVA(addend)));
continue;
}
std::string msg = getLocation(offset) + ": has non-ABS relocation " +
toString(type) + " against symbol '" + toString(sym) +
"'";
if (expr != R_PC) {
error(msg);
return;
}
// If the control reaches here, we found a PC-relative relocation in a
// non-ALLOC section. Since non-ALLOC section is not loaded into memory
// at runtime, the notion of PC-relative doesn't make sense here. So,
// this is a usage error. However, GNU linkers historically accept such
// relocations without any errors and relocate them as if they were at
// address 0. For bug-compatibility, we accept them with warnings. We
// know Steel Bank Common Lisp as of 2018 have this bug.
//
// RELA -r stopped earlier and does not get the warning. Suppress the
// warning for REL -r as well
// (https://github.com/ClangBuiltLinux/linux/issues/1937).
if (RelTy::IsRela || !config->relocatable)
warn(msg);
target.relocateNoSym(
bufLoc, type,
SignExtend64<bits>(sym.getVA(addend - offset - outSecOff)));
}
}
template <class ELFT>
void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
if ((flags & SHF_EXECINSTR) && LLVM_UNLIKELY(getFile<ELFT>()->splitStack))
adjustSplitStackFunctionPrologues<ELFT>(buf, bufEnd);
if (flags & SHF_ALLOC) {
target->relocateAlloc(*this, buf);
return;
}
auto *sec = cast<InputSection>(this);
// For a relocatable link, also call relocateNonAlloc() to rewrite applicable
// locations with tombstone values.
const RelsOrRelas<ELFT> rels = sec->template relsOrRelas<ELFT>();
if (rels.areRelocsRel())
sec->relocateNonAlloc<ELFT>(buf, rels.rels);
else
sec->relocateNonAlloc<ELFT>(buf, rels.relas);
}
// For each function-defining prologue, find any calls to __morestack,
// and replace them with calls to __morestack_non_split.
static void switchMorestackCallsToMorestackNonSplit(
DenseSet<Defined *> &prologues,
SmallVector<Relocation *, 0> &morestackCalls) {
// If the target adjusted a function's prologue, all calls to
// __morestack inside that function should be switched to
// __morestack_non_split.
Symbol *moreStackNonSplit = symtab.find("__morestack_non_split");
if (!moreStackNonSplit) {
error("mixing split-stack objects requires a definition of "
"__morestack_non_split");
return;
}
// Sort both collections to compare addresses efficiently.
llvm::sort(morestackCalls, [](const Relocation *l, const Relocation *r) {
return l->offset < r->offset;
});
std::vector<Defined *> functions(prologues.begin(), prologues.end());
llvm::sort(functions, [](const Defined *l, const Defined *r) {
return l->value < r->value;
});
auto it = morestackCalls.begin();
for (Defined *f : functions) {
// Find the first call to __morestack within the function.
while (it != morestackCalls.end() && (*it)->offset < f->value)
++it;
// Adjust all calls inside the function.
while (it != morestackCalls.end() && (*it)->offset < f->value + f->size) {
(*it)->sym = moreStackNonSplit;
++it;
}
}
}
static bool enclosingPrologueAttempted(uint64_t offset,
const DenseSet<Defined *> &prologues) {
for (Defined *f : prologues)
if (f->value <= offset && offset < f->value + f->size)
return true;
return false;
}
// If a function compiled for split stack calls a function not
// compiled for split stack, then the caller needs its prologue
// adjusted to ensure that the called function will have enough stack
// available. Find those functions, and adjust their prologues.
template <class ELFT>
void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
uint8_t *end) {
DenseSet<Defined *> prologues;
SmallVector<Relocation *, 0> morestackCalls;
for (Relocation &rel : relocs()) {
// Ignore calls into the split-stack api.
if (rel.sym->getName().starts_with("__morestack")) {
if (rel.sym->getName().equals("__morestack"))
morestackCalls.push_back(&rel);
continue;
}
// A relocation to non-function isn't relevant. Sometimes
// __morestack is not marked as a function, so this check comes
// after the name check.
if (rel.sym->type != STT_FUNC)
continue;
// If the callee's-file was compiled with split stack, nothing to do. In
// this context, a "Defined" symbol is one "defined by the binary currently
// being produced". So an "undefined" symbol might be provided by a shared
// library. It is not possible to tell how such symbols were compiled, so be
// conservative.
if (Defined *d = dyn_cast<Defined>(rel.sym))
if (InputSection *isec = cast_or_null<InputSection>(d->section))
if (!isec || !isec->getFile<ELFT>() || isec->getFile<ELFT>()->splitStack)
continue;
if (enclosingPrologueAttempted(rel.offset, prologues))
continue;
if (Defined *f = getEnclosingFunction(rel.offset)) {
prologues.insert(f);
if (target->adjustPrologueForCrossSplitStack(buf + f->value, end,
f->stOther))
continue;
if (!getFile<ELFT>()->someNoSplitStack)
error(lld::toString(this) + ": " + f->getName() +
" (with -fsplit-stack) calls " + rel.sym->getName() +
" (without -fsplit-stack), but couldn't adjust its prologue");
}
}
if (target->needsMoreStackNonSplit)
switchMorestackCallsToMorestackNonSplit(prologues, morestackCalls);
}
template <class ELFT> void InputSection::writeTo(uint8_t *buf) {
if (LLVM_UNLIKELY(type == SHT_NOBITS))
return;
// If -r or --emit-relocs is given, then an InputSection
// may be a relocation section.
if (LLVM_UNLIKELY(type == SHT_RELA)) {
copyRelocations<ELFT, typename ELFT::Rela>(buf);
return;
}
if (LLVM_UNLIKELY(type == SHT_REL)) {
copyRelocations<ELFT, typename ELFT::Rel>(buf);
return;
}
// If -r is given, we may have a SHT_GROUP section.
if (LLVM_UNLIKELY(type == SHT_GROUP)) {
copyShtGroup<ELFT>(buf);
return;
}
// If this is a compressed section, uncompress section contents directly
// to the buffer.
if (compressed) {
auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(content_);
auto compressed = ArrayRef<uint8_t>(content_, compressedSize)
.slice(sizeof(typename ELFT::Chdr));
size_t size = this->size;
if (Error e = hdr->ch_type == ELFCOMPRESS_ZLIB
? compression::zlib::decompress(compressed, buf, size)
: compression::zstd::decompress(compressed, buf, size))
fatal(toString(this) +
": decompress failed: " + llvm::toString(std::move(e)));
uint8_t *bufEnd = buf + size;
relocate<ELFT>(buf, bufEnd);
return;
}
// Copy section contents from source object file to output file
// and then apply relocations.
memcpy(buf, content().data(), content().size());
relocate<ELFT>(buf, buf + content().size());
}
void InputSection::replace(InputSection *other) {
addralign = std::max(addralign, other->addralign);
// When a section is replaced with another section that was allocated to
// another partition, the replacement section (and its associated sections)
// need to be placed in the main partition so that both partitions will be
// able to access it.
if (partition != other->partition) {
partition = 1;
for (InputSection *isec : dependentSections)
isec->partition = 1;
}
other->repl = repl;
other->markDead();
}
template <class ELFT>
EhInputSection::EhInputSection(ObjFile<ELFT> &f,
const typename ELFT::Shdr &header,
StringRef name)
: InputSectionBase(f, header, name, InputSectionBase::EHFrame) {}
SyntheticSection *EhInputSection::getParent() const {
return cast_or_null<SyntheticSection>(parent);
}
// .eh_frame is a sequence of CIE or FDE records.
// This function splits an input section into records and returns them.
template <class ELFT> void EhInputSection::split() {
const RelsOrRelas<ELFT> rels = relsOrRelas<ELFT>();
// getReloc expects the relocations to be sorted by r_offset. See the comment
// in scanRelocs.
if (rels.areRelocsRel()) {
SmallVector<typename ELFT::Rel, 0> storage;
split<ELFT>(sortRels(rels.rels, storage));
} else {
SmallVector<typename ELFT::Rela, 0> storage;
split<ELFT>(sortRels(rels.relas, storage));
}
}
template <class ELFT, class RelTy>
void EhInputSection::split(ArrayRef<RelTy> rels) {
ArrayRef<uint8_t> d = content();
const char *msg = nullptr;
unsigned relI = 0;
while (!d.empty()) {
if (d.size() < 4) {
msg = "CIE/FDE too small";
break;
}
uint64_t size = endian::read32<ELFT::TargetEndianness>(d.data());
if (size == 0) // ZERO terminator
break;
uint32_t id = endian::read32<ELFT::TargetEndianness>(d.data() + 4);
size += 4;
if (LLVM_UNLIKELY(size > d.size())) {
// If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
// but we do not support that format yet.
msg = size == UINT32_MAX + uint64_t(4)
? "CIE/FDE too large"
: "CIE/FDE ends past the end of the section";
break;
}
// Find the first relocation that points to [off,off+size). Relocations
// have been sorted by r_offset.
const uint64_t off = d.data() - content().data();
while (relI != rels.size() && rels[relI].r_offset < off)
++relI;
unsigned firstRel = -1;
if (relI != rels.size() && rels[relI].r_offset < off + size)
firstRel = relI;
(id == 0 ? cies : fdes).emplace_back(off, this, size, firstRel);
d = d.slice(size);
}
if (msg)
errorOrWarn("corrupted .eh_frame: " + Twine(msg) + "\n>>> defined in " +
getObjMsg(d.data() - content().data()));
}
// Return the offset in an output section for a given input offset.
uint64_t EhInputSection::getParentOffset(uint64_t offset) const {
auto it = partition_point(
fdes, [=](EhSectionPiece p) { return p.inputOff <= offset; });
if (it == fdes.begin() || it[-1].inputOff + it[-1].size <= offset) {
it = partition_point(
cies, [=](EhSectionPiece p) { return p.inputOff <= offset; });
if (it == cies.begin()) // invalid piece
return offset;
}
if (it[-1].outputOff == -1) // invalid piece
return offset - it[-1].inputOff;
return it[-1].outputOff + (offset - it[-1].inputOff);
}
static size_t findNull(StringRef s, size_t entSize) {
for (unsigned i = 0, n = s.size(); i != n; i += entSize) {
const char *b = s.begin() + i;
if (std::all_of(b, b + entSize, [](char c) { return c == 0; }))
return i;
}
llvm_unreachable("");
}
// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
void MergeInputSection::splitStrings(StringRef s, size_t entSize) {
const bool live = !(flags & SHF_ALLOC) || !config->gcSections;
const char *p = s.data(), *end = s.data() + s.size();
if (!std::all_of(end - entSize, end, [](char c) { return c == 0; }))
fatal(toString(this) + ": string is not null terminated");
if (entSize == 1) {
// Optimize the common case.
do {
size_t size = strlen(p);
pieces.emplace_back(p - s.begin(), xxh3_64bits(StringRef(p, size)), live);
p += size + 1;
} while (p != end);
} else {
do {
size_t size = findNull(StringRef(p, end - p), entSize);
pieces.emplace_back(p - s.begin(), xxh3_64bits(StringRef(p, size)), live);
p += size + entSize;
} while (p != end);
}
}
// Split non-SHF_STRINGS section. Such section is a sequence of
// fixed size records.
void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> data,
size_t entSize) {
size_t size = data.size();
assert((size % entSize) == 0);
const bool live = !(flags & SHF_ALLOC) || !config->gcSections;
pieces.resize_for_overwrite(size / entSize);
for (size_t i = 0, j = 0; i != size; i += entSize, j++)
pieces[j] = {i, (uint32_t)xxh3_64bits(data.slice(i, entSize)), live};
}
template <class ELFT>
MergeInputSection::MergeInputSection(ObjFile<ELFT> &f,
const typename ELFT::Shdr &header,
StringRef name)
: InputSectionBase(f, header, name, InputSectionBase::Merge) {}
MergeInputSection::MergeInputSection(uint64_t flags, uint32_t type,
uint64_t entsize, ArrayRef<uint8_t> data,
StringRef name)
: InputSectionBase(nullptr, flags, type, entsize, /*Link*/ 0, /*Info*/ 0,
/*Alignment*/ entsize, data, name, SectionBase::Merge) {}
// This function is called after we obtain a complete list of input sections
// that need to be linked. This is responsible to split section contents
// into small chunks for further processing.
//
// Note that this function is called from parallelForEach. This must be
// thread-safe (i.e. no memory allocation from the pools).
void MergeInputSection::splitIntoPieces() {
assert(pieces.empty());
if (flags & SHF_STRINGS)
splitStrings(toStringRef(contentMaybeDecompress()), entsize);
else
splitNonStrings(contentMaybeDecompress(), entsize);
}
SectionPiece &MergeInputSection::getSectionPiece(uint64_t offset) {
if (content().size() <= offset)
fatal(toString(this) + ": offset is outside the section");
return partition_point(
pieces, [=](SectionPiece p) { return p.inputOff <= offset; })[-1];
}
// Return the offset in an output section for a given input offset.
uint64_t MergeInputSection::getParentOffset(uint64_t offset) const {
const SectionPiece &piece = getSectionPiece(offset);
return piece.outputOff + (offset - piece.inputOff);
}
template InputSection::InputSection(ObjFile<ELF32LE> &, const ELF32LE::Shdr &,
StringRef);
template InputSection::InputSection(ObjFile<ELF32BE> &, const ELF32BE::Shdr &,
StringRef);
template InputSection::InputSection(ObjFile<ELF64LE> &, const ELF64LE::Shdr &,
StringRef);
template InputSection::InputSection(ObjFile<ELF64BE> &, const ELF64BE::Shdr &,
StringRef);
template void InputSection::writeTo<ELF32LE>(uint8_t *);
template void InputSection::writeTo<ELF32BE>(uint8_t *);
template void InputSection::writeTo<ELF64LE>(uint8_t *);
template void InputSection::writeTo<ELF64BE>(uint8_t *);
template RelsOrRelas<ELF32LE> InputSectionBase::relsOrRelas<ELF32LE>() const;
template RelsOrRelas<ELF32BE> InputSectionBase::relsOrRelas<ELF32BE>() const;
template RelsOrRelas<ELF64LE> InputSectionBase::relsOrRelas<ELF64LE>() const;
template RelsOrRelas<ELF64BE> InputSectionBase::relsOrRelas<ELF64BE>() const;
template MergeInputSection::MergeInputSection(ObjFile<ELF32LE> &,
const ELF32LE::Shdr &, StringRef);
template MergeInputSection::MergeInputSection(ObjFile<ELF32BE> &,
const ELF32BE::Shdr &, StringRef);
template MergeInputSection::MergeInputSection(ObjFile<ELF64LE> &,
const ELF64LE::Shdr &, StringRef);
template MergeInputSection::MergeInputSection(ObjFile<ELF64BE> &,
const ELF64BE::Shdr &, StringRef);
template EhInputSection::EhInputSection(ObjFile<ELF32LE> &,
const ELF32LE::Shdr &, StringRef);
template EhInputSection::EhInputSection(ObjFile<ELF32BE> &,
const ELF32BE::Shdr &, StringRef);
template EhInputSection::EhInputSection(ObjFile<ELF64LE> &,
const ELF64LE::Shdr &, StringRef);
template EhInputSection::EhInputSection(ObjFile<ELF64BE> &,
const ELF64BE::Shdr &, StringRef);
template void EhInputSection::split<ELF32LE>();
template void EhInputSection::split<ELF32BE>();
template void EhInputSection::split<ELF64LE>();
template void EhInputSection::split<ELF64BE>();
|