Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
ELFObject.cpp
Go to the documentation of this file.
1//===- ELFObject.cpp ------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ELFObject.h"
10#include "llvm/ADT/ArrayRef.h"
11#include "llvm/ADT/STLExtras.h"
12#include "llvm/ADT/StringRef.h"
13#include "llvm/ADT/Twine.h"
14#include "llvm/ADT/iterator_range.h"
15#include "llvm/BinaryFormat/ELF.h"
16#include "llvm/MC/MCELFExtras.h"
17#include "llvm/MC/MCTargetOptions.h"
18#include "llvm/Support/Compression.h"
19#include "llvm/Support/Endian.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/Path.h"
22#include <algorithm>
23#include <cstddef>
24#include <cstdint>
25#include <iterator>
26#include <unordered_set>
27#include <utility>
28#include <vector>
29
30using namespacellvm;
31using namespacellvm::ELF;
32using namespacellvm::objcopy::elf;
33using namespacellvm::object;
34using namespacellvm::support;
35
36template <class ELFT>voidELFWriter<ELFT>::writePhdr(constSegment &Seg) {
37uint8_t *B =reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +
38 Obj.ProgramHdrSegment.Offset + Seg.Index *sizeof(Elf_Phdr);
39 Elf_Phdr &Phdr = *reinterpret_cast<Elf_Phdr *>(B);
40 Phdr.p_type = Seg.Type;
41 Phdr.p_flags = Seg.Flags;
42 Phdr.p_offset = Seg.Offset;
43 Phdr.p_vaddr = Seg.VAddr;
44 Phdr.p_paddr = Seg.PAddr;
45 Phdr.p_filesz = Seg.FileSize;
46 Phdr.p_memsz = Seg.MemSize;
47 Phdr.p_align = Seg.Align;
48}
49
50ErrorSectionBase::removeSectionReferences(
51bool,function_ref<bool(constSectionBase *)>) {
52returnError::success();
53}
54
55ErrorSectionBase::removeSymbols(function_ref<bool(constSymbol &)>) {
56returnError::success();
57}
58
59ErrorSectionBase::initialize(SectionTableRef) {returnError::success(); }
60voidSectionBase::finalize() {}
61voidSectionBase::markSymbols() {}
62voidSectionBase::replaceSectionReferences(
63constDenseMap<SectionBase *, SectionBase *> &) {}
64voidSectionBase::onRemove() {}
65
66template <class ELFT>voidELFWriter<ELFT>::writeShdr(constSectionBase &Sec) {
67uint8_t *B =
68reinterpret_cast<uint8_t *>(Buf->getBufferStart()) + Sec.HeaderOffset;
69 Elf_Shdr &Shdr = *reinterpret_cast<Elf_Shdr *>(B);
70Shdr.sh_name = Sec.NameIndex;
71Shdr.sh_type = Sec.Type;
72Shdr.sh_flags = Sec.Flags;
73Shdr.sh_addr = Sec.Addr;
74Shdr.sh_offset = Sec.Offset;
75Shdr.sh_size = Sec.Size;
76Shdr.sh_link = Sec.Link;
77Shdr.sh_info = Sec.Info;
78Shdr.sh_addralign = Sec.Align;
79Shdr.sh_entsize = Sec.EntrySize;
80}
81
82template <class ELFT>ErrorELFSectionSizer<ELFT>::visit(Section &) {
83returnError::success();
84}
85
86template <class ELFT>ErrorELFSectionSizer<ELFT>::visit(OwnedDataSection &) {
87returnError::success();
88}
89
90template <class ELFT>ErrorELFSectionSizer<ELFT>::visit(StringTableSection &) {
91returnError::success();
92}
93
94template <class ELFT>
95ErrorELFSectionSizer<ELFT>::visit(DynamicRelocationSection &) {
96returnError::success();
97}
98
99template <class ELFT>
100ErrorELFSectionSizer<ELFT>::visit(SymbolTableSection &Sec) {
101 Sec.EntrySize =sizeof(Elf_Sym);
102 Sec.Size = Sec.Symbols.size() * Sec.EntrySize;
103// Align to the largest field in Elf_Sym.
104 Sec.Align = ELFT::Is64Bits ?sizeof(Elf_Xword) :sizeof(Elf_Word);
105returnError::success();
106}
107
108template <bool Is64>
109staticSmallVector<char, 0>encodeCrel(ArrayRef<Relocation> Relocations) {
110usinguint = std::conditional_t<Is64, uint64_t, uint32_t>;
111SmallVector<char, 0>Content;
112raw_svector_ostreamOS(Content);
113 ELF::encodeCrel<Is64>(OS, Relocations, [&](constRelocation &R) {
114uint32_t CurSymIdx = R.RelocSymbol ? R.RelocSymbol->Index : 0;
115returnELF::Elf_Crel<Is64>{static_cast<uint>(R.Offset), CurSymIdx, R.Type,
116 std::make_signed_t<uint>(R.Addend)};
117 });
118returnContent;
119}
120
121template <class ELFT>
122ErrorELFSectionSizer<ELFT>::visit(RelocationSection &Sec) {
123if (Sec.Type ==SHT_CREL) {
124 Sec.Size = encodeCrel<ELFT::Is64Bits>(Sec.Relocations).size();
125 }else {
126 Sec.EntrySize = Sec.Type ==SHT_REL ?sizeof(Elf_Rel) :sizeof(Elf_Rela);
127 Sec.Size = Sec.Relocations.size() * Sec.EntrySize;
128// Align to the largest field in Elf_Rel(a).
129 Sec.Align = ELFT::Is64Bits ?sizeof(Elf_Xword) :sizeof(Elf_Word);
130 }
131returnError::success();
132}
133
134template <class ELFT>
135ErrorELFSectionSizer<ELFT>::visit(GnuDebugLinkSection &) {
136returnError::success();
137}
138
139template <class ELFT>ErrorELFSectionSizer<ELFT>::visit(GroupSection &Sec) {
140 Sec.Size =sizeof(Elf_Word) + Sec.GroupMembers.size() *sizeof(Elf_Word);
141returnError::success();
142}
143
144template <class ELFT>
145ErrorELFSectionSizer<ELFT>::visit(SectionIndexSection &) {
146returnError::success();
147}
148
149template <class ELFT>ErrorELFSectionSizer<ELFT>::visit(CompressedSection &) {
150returnError::success();
151}
152
153template <class ELFT>
154ErrorELFSectionSizer<ELFT>::visit(DecompressedSection &) {
155returnError::success();
156}
157
158ErrorBinarySectionWriter::visit(constSectionIndexSection &Sec) {
159returncreateStringError(errc::operation_not_permitted,
160"cannot write symbol section index table '" +
161 Sec.Name +"' ");
162}
163
164ErrorBinarySectionWriter::visit(constSymbolTableSection &Sec) {
165returncreateStringError(errc::operation_not_permitted,
166"cannot write symbol table '" + Sec.Name +
167"' out to binary");
168}
169
170ErrorBinarySectionWriter::visit(constRelocationSection &Sec) {
171returncreateStringError(errc::operation_not_permitted,
172"cannot write relocation section '" + Sec.Name +
173"' out to binary");
174}
175
176ErrorBinarySectionWriter::visit(constGnuDebugLinkSection &Sec) {
177returncreateStringError(errc::operation_not_permitted,
178"cannot write '" + Sec.Name +"' out to binary");
179}
180
181ErrorBinarySectionWriter::visit(constGroupSection &Sec) {
182returncreateStringError(errc::operation_not_permitted,
183"cannot write '" + Sec.Name +"' out to binary");
184}
185
186ErrorSectionWriter::visit(constSection &Sec) {
187if (Sec.Type !=SHT_NOBITS)
188llvm::copy(Sec.Contents,Out.getBufferStart() + Sec.Offset);
189
190returnError::success();
191}
192
193staticbooladdressOverflows32bit(uint64_tAddr) {
194// Sign extended 32 bit addresses (e.g 0xFFFFFFFF80000000) are ok
195returnAddr > UINT32_MAX &&Addr + 0x80000000 > UINT32_MAX;
196}
197
198template <class T>staticTcheckedGetHex(StringRef S) {
199TValue;
200boolFail = S.getAsInteger(16,Value);
201assert(!Fail);
202 (void)Fail;
203returnValue;
204}
205
206// Fills exactly Len bytes of buffer with hexadecimal characters
207// representing value 'X'
208template <class T,class Iterator>
209static IteratortoHexStr(TX, Iterator It,size_t Len) {
210// Fill range with '0'
211 std::fill(It, It + Len,'0');
212
213for (longI = Len - 1;I >= 0; --I) {
214unsignedcharMod =static_cast<unsignedchar>(X) & 15;
215 *(It +I) = hexdigit(Mod,false);
216X >>= 4;
217 }
218assert(X == 0);
219return It + Len;
220}
221
222uint8_tIHexRecord::getChecksum(StringRef S) {
223assert((S.size() & 1) == 0);
224uint8_t Checksum = 0;
225while (!S.empty()) {
226 Checksum += checkedGetHex<uint8_t>(S.take_front(2));
227 S = S.drop_front(2);
228 }
229return -Checksum;
230}
231
232IHexLineDataIHexRecord::getLine(uint8_tType,uint16_tAddr,
233ArrayRef<uint8_t>Data) {
234IHexLineData Line(getLineLength(Data.size()));
235assert(Line.size());
236auto Iter = Line.begin();
237 *Iter++ =':';
238 Iter =toHexStr(Data.size(), Iter, 2);
239 Iter =toHexStr(Addr, Iter, 4);
240 Iter =toHexStr(Type, Iter, 2);
241for (uint8_tX :Data)
242 Iter =toHexStr(X, Iter, 2);
243StringRef S(Line.data() + 1, std::distance(Line.begin() + 1, Iter));
244 Iter =toHexStr(getChecksum(S), Iter, 2);
245 *Iter++ ='\r';
246 *Iter++ ='\n';
247assert(Iter == Line.end());
248return Line;
249}
250
251staticErrorcheckRecord(constIHexRecord &R) {
252switch (R.Type) {
253caseIHexRecord::Data:
254if (R.HexData.size() == 0)
255returncreateStringError(
256errc::invalid_argument,
257"zero data length is not allowed for data records");
258break;
259caseIHexRecord::EndOfFile:
260break;
261caseIHexRecord::SegmentAddr:
262// 20-bit segment address. Data length must be 2 bytes
263// (4 bytes in hex)
264if (R.HexData.size() != 4)
265returncreateStringError(
266errc::invalid_argument,
267"segment address data should be 2 bytes in size");
268break;
269caseIHexRecord::StartAddr80x86:
270caseIHexRecord::StartAddr:
271if (R.HexData.size() != 8)
272returncreateStringError(errc::invalid_argument,
273"start address data should be 4 bytes in size");
274// According to Intel HEX specification '03' record
275// only specifies the code address within the 20-bit
276// segmented address space of the 8086/80186. This
277// means 12 high order bits should be zeroes.
278if (R.Type ==IHexRecord::StartAddr80x86 &&
279 R.HexData.take_front(3) !="000")
280returncreateStringError(errc::invalid_argument,
281"start address exceeds 20 bit for 80x86");
282break;
283caseIHexRecord::ExtendedAddr:
284// 16-31 bits of linear base address
285if (R.HexData.size() != 4)
286returncreateStringError(
287errc::invalid_argument,
288"extended address data should be 2 bytes in size");
289break;
290default:
291// Unknown record type
292returncreateStringError(errc::invalid_argument,"unknown record type: %u",
293static_cast<unsigned>(R.Type));
294 }
295returnError::success();
296}
297
298// Checks that IHEX line contains valid characters.
299// This allows converting hexadecimal data to integers
300// without extra verification.
301staticErrorcheckChars(StringRef Line) {
302assert(!Line.empty());
303if (Line[0] !=':')
304returncreateStringError(errc::invalid_argument,
305"missing ':' in the beginning of line.");
306
307for (size_t Pos = 1; Pos < Line.size(); ++Pos)
308if (hexDigitValue(Line[Pos]) == -1U)
309returncreateStringError(errc::invalid_argument,
310"invalid character at position %zu.", Pos + 1);
311returnError::success();
312}
313
314Expected<IHexRecord>IHexRecord::parse(StringRef Line) {
315assert(!Line.empty());
316
317// ':' + Length + Address + Type + Checksum with empty data ':LLAAAATTCC'
318if (Line.size() < 11)
319returncreateStringError(errc::invalid_argument,
320"line is too short: %zu chars.", Line.size());
321
322if (Error E =checkChars(Line))
323return std::move(E);
324
325IHexRecord Rec;
326size_t DataLen = checkedGetHex<uint8_t>(Line.substr(1, 2));
327if (Line.size() !=getLength(DataLen))
328returncreateStringError(errc::invalid_argument,
329"invalid line length %zu (should be %zu)",
330 Line.size(),getLength(DataLen));
331
332 Rec.Addr = checkedGetHex<uint16_t>(Line.substr(3, 4));
333 Rec.Type = checkedGetHex<uint8_t>(Line.substr(7, 2));
334 Rec.HexData = Line.substr(9, DataLen * 2);
335
336if (getChecksum(Line.drop_front(1)) != 0)
337returncreateStringError(errc::invalid_argument,"incorrect checksum.");
338if (Error E =checkRecord(Rec))
339return std::move(E);
340return Rec;
341}
342
343staticuint64_tsectionPhysicalAddr(constSectionBase *Sec) {
344Segment *Seg = Sec->ParentSegment;
345if (Seg && Seg->Type !=ELF::PT_LOAD)
346 Seg =nullptr;
347return Seg ? Seg->PAddr + Sec->OriginalOffset - Seg->OriginalOffset
348 : Sec->Addr;
349}
350
351voidIHexSectionWriterBase::writeSection(constSectionBase *Sec,
352ArrayRef<uint8_t>Data) {
353assert(Data.size() == Sec->Size);
354constuint32_t ChunkSize = 16;
355uint32_tAddr =sectionPhysicalAddr(Sec) & 0xFFFFFFFFU;
356while (!Data.empty()) {
357uint64_t DataSize = std::min<uint64_t>(Data.size(), ChunkSize);
358if (Addr > SegmentAddr + BaseAddr + 0xFFFFU) {
359if (Addr > 0xFFFFFU) {
360// Write extended address record, zeroing segment address
361// if needed.
362if (SegmentAddr != 0)
363 SegmentAddr = writeSegmentAddr(0U);
364 BaseAddr = writeBaseAddr(Addr);
365 }else {
366// We can still remain 16-bit
367 SegmentAddr = writeSegmentAddr(Addr);
368 }
369 }
370uint64_t SegOffset =Addr - BaseAddr - SegmentAddr;
371assert(SegOffset <= 0xFFFFU);
372 DataSize = std::min(DataSize, 0x10000U - SegOffset);
373writeData(0, SegOffset,Data.take_front(DataSize));
374Addr += DataSize;
375Data =Data.drop_front(DataSize);
376 }
377}
378
379uint64_t IHexSectionWriterBase::writeSegmentAddr(uint64_tAddr) {
380assert(Addr <= 0xFFFFFU);
381uint8_tData[] = {static_cast<uint8_t>((Addr & 0xF0000U) >> 12), 0};
382writeData(2, 0,Data);
383returnAddr & 0xF0000U;
384}
385
386uint64_t IHexSectionWriterBase::writeBaseAddr(uint64_tAddr) {
387assert(Addr <= 0xFFFFFFFFU);
388uint64_tBase =Addr & 0xFFFF0000U;
389uint8_tData[] = {static_cast<uint8_t>(Base >> 24),
390static_cast<uint8_t>((Base >> 16) & 0xFF)};
391writeData(4, 0,Data);
392returnBase;
393}
394
395voidIHexSectionWriterBase::writeData(uint8_t,uint16_t,
396ArrayRef<uint8_t>Data) {
397Offset +=IHexRecord::getLineLength(Data.size());
398}
399
400ErrorIHexSectionWriterBase::visit(constSection &Sec) {
401writeSection(&Sec, Sec.Contents);
402returnError::success();
403}
404
405ErrorIHexSectionWriterBase::visit(constOwnedDataSection &Sec) {
406writeSection(&Sec, Sec.Data);
407returnError::success();
408}
409
410ErrorIHexSectionWriterBase::visit(constStringTableSection &Sec) {
411// Check that sizer has already done its work
412assert(Sec.Size == Sec.StrTabBuilder.getSize());
413// We are free to pass an invalid pointer to writeSection as long
414// as we don't actually write any data. The real writer class has
415// to override this method .
416writeSection(&Sec, {nullptr,static_cast<size_t>(Sec.Size)});
417returnError::success();
418}
419
420ErrorIHexSectionWriterBase::visit(constDynamicRelocationSection &Sec) {
421writeSection(&Sec, Sec.Contents);
422returnError::success();
423}
424
425voidIHexSectionWriter::writeData(uint8_tType,uint16_tAddr,
426ArrayRef<uint8_t>Data) {
427IHexLineData HexData =IHexRecord::getLine(Type,Addr,Data);
428 memcpy(Out.getBufferStart() +Offset, HexData.data(), HexData.size());
429Offset += HexData.size();
430}
431
432ErrorIHexSectionWriter::visit(constStringTableSection &Sec) {
433assert(Sec.Size == Sec.StrTabBuilder.getSize());
434 std::vector<uint8_t>Data(Sec.Size);
435 Sec.StrTabBuilder.write(Data.data());
436writeSection(&Sec,Data);
437returnError::success();
438}
439
440ErrorSection::accept(SectionVisitor &Visitor) const{
441return Visitor.visit(*this);
442}
443
444ErrorSection::accept(MutableSectionVisitor &Visitor) {
445return Visitor.visit(*this);
446}
447
448voidSection::restoreSymTabLink(SymbolTableSection &SymTab) {
449if (HasSymTabLink) {
450assert(LinkSection ==nullptr);
451 LinkSection = &SymTab;
452 }
453}
454
455ErrorSectionWriter::visit(constOwnedDataSection &Sec) {
456llvm::copy(Sec.Data,Out.getBufferStart() + Sec.Offset);
457returnError::success();
458}
459
460template <class ELFT>
461ErrorELFSectionWriter<ELFT>::visit(constDecompressedSection &Sec) {
462ArrayRef<uint8_t> Compressed =
463 Sec.OriginalData.slice(sizeof(Elf_Chdr_Impl<ELFT>));
464SmallVector<uint8_t, 128> Decompressed;
465DebugCompressionTypeType;
466switch (Sec.ChType) {
467caseELFCOMPRESS_ZLIB:
468Type =DebugCompressionType::Zlib;
469break;
470caseELFCOMPRESS_ZSTD:
471Type =DebugCompressionType::Zstd;
472break;
473default:
474returncreateStringError(errc::invalid_argument,
475"--decompress-debug-sections: ch_type (" +
476Twine(Sec.ChType) +") of section '" +
477 Sec.Name +"' is unsupported");
478 }
479if (auto *Reason =
480compression::getReasonIfUnsupported(compression::formatFor(Type)))
481returncreateStringError(errc::invalid_argument,
482"failed to decompress section '" + Sec.Name +
483"': " + Reason);
484if (Error E =compression::decompress(Type, Compressed, Decompressed,
485static_cast<size_t>(Sec.Size)))
486returncreateStringError(errc::invalid_argument,
487"failed to decompress section '" + Sec.Name +
488"': " +toString(std::move(E)));
489
490uint8_t *Buf =reinterpret_cast<uint8_t *>(Out.getBufferStart()) + Sec.Offset;
491 std::copy(Decompressed.begin(), Decompressed.end(), Buf);
492
493returnError::success();
494}
495
496ErrorBinarySectionWriter::visit(constDecompressedSection &Sec) {
497returncreateStringError(errc::operation_not_permitted,
498"cannot write compressed section '" + Sec.Name +
499"' ");
500}
501
502ErrorDecompressedSection::accept(SectionVisitor &Visitor) const{
503return Visitor.visit(*this);
504}
505
506ErrorDecompressedSection::accept(MutableSectionVisitor &Visitor) {
507return Visitor.visit(*this);
508}
509
510ErrorOwnedDataSection::accept(SectionVisitor &Visitor) const{
511return Visitor.visit(*this);
512}
513
514ErrorOwnedDataSection::accept(MutableSectionVisitor &Visitor) {
515return Visitor.visit(*this);
516}
517
518voidOwnedDataSection::appendHexData(StringRef HexData) {
519assert((HexData.size() & 1) == 0);
520while (!HexData.empty()) {
521 Data.push_back(checkedGetHex<uint8_t>(HexData.take_front(2)));
522 HexData = HexData.drop_front(2);
523 }
524Size = Data.size();
525}
526
527ErrorBinarySectionWriter::visit(constCompressedSection &Sec) {
528returncreateStringError(errc::operation_not_permitted,
529"cannot write compressed section '" + Sec.Name +
530"' ");
531}
532
533template <class ELFT>
534ErrorELFSectionWriter<ELFT>::visit(constCompressedSection &Sec) {
535uint8_t *Buf =reinterpret_cast<uint8_t *>(Out.getBufferStart()) + Sec.Offset;
536Elf_Chdr_Impl<ELFT> Chdr = {};
537switch (Sec.CompressionType) {
538caseDebugCompressionType::None:
539 std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(), Buf);
540returnError::success();
541caseDebugCompressionType::Zlib:
542 Chdr.ch_type =ELF::ELFCOMPRESS_ZLIB;
543break;
544caseDebugCompressionType::Zstd:
545 Chdr.ch_type =ELF::ELFCOMPRESS_ZSTD;
546break;
547 }
548 Chdr.ch_size = Sec.DecompressedSize;
549 Chdr.ch_addralign = Sec.DecompressedAlign;
550 memcpy(Buf, &Chdr,sizeof(Chdr));
551 Buf +=sizeof(Chdr);
552
553 std::copy(Sec.CompressedData.begin(), Sec.CompressedData.end(), Buf);
554returnError::success();
555}
556
557CompressedSection::CompressedSection(constSectionBase &Sec,
558DebugCompressionType CompressionType,
559bool Is64Bits)
560 :SectionBase(Sec), CompressionType(CompressionType),
561 DecompressedSize(Sec.OriginalData.size()), DecompressedAlign(Sec.Align) {
562compression::compress(compression::Params(CompressionType),OriginalData,
563 CompressedData);
564
565Flags |=ELF::SHF_COMPRESSED;
566OriginalFlags |=ELF::SHF_COMPRESSED;
567size_t ChdrSize = Is64Bits ?sizeof(object::Elf_Chdr_Impl<object::ELF64LE>)
568 :sizeof(object::Elf_Chdr_Impl<object::ELF32LE>);
569Size = ChdrSize + CompressedData.size();
570Align = 8;
571}
572
573CompressedSection::CompressedSection(ArrayRef<uint8_t> CompressedData,
574uint32_t ChType,uint64_t DecompressedSize,
575uint64_t DecompressedAlign)
576 : ChType(ChType), CompressionType(DebugCompressionType::None),
577 DecompressedSize(DecompressedSize), DecompressedAlign(DecompressedAlign) {
578OriginalData = CompressedData;
579}
580
581ErrorCompressedSection::accept(SectionVisitor &Visitor) const{
582return Visitor.visit(*this);
583}
584
585ErrorCompressedSection::accept(MutableSectionVisitor &Visitor) {
586return Visitor.visit(*this);
587}
588
589voidStringTableSection::addString(StringRefName) { StrTabBuilder.add(Name); }
590
591uint32_tStringTableSection::findIndex(StringRefName) const{
592return StrTabBuilder.getOffset(Name);
593}
594
595voidStringTableSection::prepareForLayout() {
596 StrTabBuilder.finalize();
597Size = StrTabBuilder.getSize();
598}
599
600ErrorSectionWriter::visit(constStringTableSection &Sec) {
601 Sec.StrTabBuilder.write(reinterpret_cast<uint8_t *>(Out.getBufferStart()) +
602 Sec.Offset);
603returnError::success();
604}
605
606ErrorStringTableSection::accept(SectionVisitor &Visitor) const{
607return Visitor.visit(*this);
608}
609
610ErrorStringTableSection::accept(MutableSectionVisitor &Visitor) {
611return Visitor.visit(*this);
612}
613
614template <class ELFT>
615ErrorELFSectionWriter<ELFT>::visit(constSectionIndexSection &Sec) {
616uint8_t *Buf =reinterpret_cast<uint8_t *>(Out.getBufferStart()) + Sec.Offset;
617llvm::copy(Sec.Indexes,reinterpret_cast<Elf_Word *>(Buf));
618returnError::success();
619}
620
621ErrorSectionIndexSection::initialize(SectionTableRef SecTable) {
622Size = 0;
623Expected<SymbolTableSection *> Sec =
624 SecTable.getSectionOfType<SymbolTableSection>(
625Link,
626"Link field value " +Twine(Link) +" in section " +Name +
627" is invalid",
628"Link field value " +Twine(Link) +" in section " +Name +
629" is not a symbol table");
630if (!Sec)
631return Sec.takeError();
632
633setSymTab(*Sec);
634 Symbols->setShndxTable(this);
635returnError::success();
636}
637
638voidSectionIndexSection::finalize() {Link = Symbols->Index; }
639
640ErrorSectionIndexSection::accept(SectionVisitor &Visitor) const{
641return Visitor.visit(*this);
642}
643
644ErrorSectionIndexSection::accept(MutableSectionVisitor &Visitor) {
645return Visitor.visit(*this);
646}
647
648staticboolisValidReservedSectionIndex(uint16_t Index,uint16_tMachine) {
649switch (Index) {
650caseSHN_ABS:
651caseSHN_COMMON:
652returntrue;
653 }
654
655if (Machine ==EM_AMDGPU) {
656return Index ==SHN_AMDGPU_LDS;
657 }
658
659if (Machine ==EM_MIPS) {
660switch (Index) {
661caseSHN_MIPS_ACOMMON:
662caseSHN_MIPS_SCOMMON:
663caseSHN_MIPS_SUNDEFINED:
664returntrue;
665 }
666 }
667
668if (Machine ==EM_HEXAGON) {
669switch (Index) {
670caseSHN_HEXAGON_SCOMMON:
671caseSHN_HEXAGON_SCOMMON_1:
672caseSHN_HEXAGON_SCOMMON_2:
673caseSHN_HEXAGON_SCOMMON_4:
674caseSHN_HEXAGON_SCOMMON_8:
675returntrue;
676 }
677 }
678returnfalse;
679}
680
681// Large indexes force us to clarify exactly what this function should do. This
682// function should return the value that will appear in st_shndx when written
683// out.
684uint16_tSymbol::getShndx() const{
685if (DefinedIn !=nullptr) {
686if (DefinedIn->Index >=SHN_LORESERVE)
687returnSHN_XINDEX;
688returnDefinedIn->Index;
689 }
690
691if (ShndxType ==SYMBOL_SIMPLE_INDEX) {
692// This means that we don't have a defined section but we do need to
693// output a legitimate section index.
694returnSHN_UNDEF;
695 }
696
697assert(ShndxType ==SYMBOL_ABS ||ShndxType ==SYMBOL_COMMON ||
698 (ShndxType >=SYMBOL_LOPROC &&ShndxType <=SYMBOL_HIPROC) ||
699 (ShndxType >=SYMBOL_LOOS &&ShndxType <=SYMBOL_HIOS));
700returnstatic_cast<uint16_t>(ShndxType);
701}
702
703boolSymbol::isCommon() const{returngetShndx() ==SHN_COMMON; }
704
705void SymbolTableSection::assignIndices() {
706uint32_tIndex = 0;
707for (auto &Sym :Symbols) {
708if (Sym->Index !=Index)
709IndicesChanged =true;
710Sym->Index =Index++;
711 }
712}
713
714voidSymbolTableSection::addSymbol(TwineName,uint8_t Bind,uint8_tType,
715SectionBase *DefinedIn,uint64_tValue,
716uint8_t Visibility,uint16_t Shndx,
717uint64_t SymbolSize) {
718SymbolSym;
719Sym.Name =Name.str();
720Sym.Binding = Bind;
721Sym.Type =Type;
722Sym.DefinedIn = DefinedIn;
723if (DefinedIn !=nullptr)
724 DefinedIn->HasSymbol =true;
725if (DefinedIn ==nullptr) {
726if (Shndx >=SHN_LORESERVE)
727Sym.ShndxType =static_cast<SymbolShndxType>(Shndx);
728else
729Sym.ShndxType =SYMBOL_SIMPLE_INDEX;
730 }
731Sym.Value =Value;
732Sym.Visibility = Visibility;
733Sym.Size = SymbolSize;
734Sym.Index =Symbols.size();
735Symbols.emplace_back(std::make_unique<Symbol>(Sym));
736Size += this->EntrySize;
737}
738
739ErrorSymbolTableSection::removeSectionReferences(
740bool AllowBrokenLinks,function_ref<bool(constSectionBase *)>ToRemove) {
741if (ToRemove(SectionIndexTable))
742SectionIndexTable =nullptr;
743if (ToRemove(SymbolNames)) {
744if (!AllowBrokenLinks)
745returncreateStringError(
746llvm::errc::invalid_argument,
747"string table '%s' cannot be removed because it is "
748"referenced by the symbol table '%s'",
749SymbolNames->Name.data(), this->Name.data());
750SymbolNames =nullptr;
751 }
752returnremoveSymbols(
753 [ToRemove](constSymbol &Sym) {returnToRemove(Sym.DefinedIn); });
754}
755
756voidSymbolTableSection::updateSymbols(function_ref<void(Symbol &)> Callable) {
757for (SymPtr &Sym :llvm::drop_begin(Symbols))
758 Callable(*Sym);
759 std::stable_partition(
760 std::begin(Symbols), std::end(Symbols),
761 [](constSymPtr &Sym) {returnSym->Binding ==STB_LOCAL; });
762 assignIndices();
763}
764
765ErrorSymbolTableSection::removeSymbols(
766function_ref<bool(constSymbol &)>ToRemove) {
767Symbols.erase(
768 std::remove_if(std::begin(Symbols) + 1, std::end(Symbols),
769 [ToRemove](constSymPtr &Sym) {returnToRemove(*Sym); }),
770 std::end(Symbols));
771auto PrevSize =Size;
772Size =Symbols.size() *EntrySize;
773if (Size < PrevSize)
774IndicesChanged =true;
775 assignIndices();
776returnError::success();
777}
778
779voidSymbolTableSection::replaceSectionReferences(
780constDenseMap<SectionBase *, SectionBase *> &FromTo) {
781for (std::unique_ptr<Symbol> &Sym :Symbols)
782if (SectionBase *To = FromTo.lookup(Sym->DefinedIn))
783Sym->DefinedIn = To;
784}
785
786ErrorSymbolTableSection::initialize(SectionTableRef SecTable) {
787Size = 0;
788Expected<StringTableSection *> Sec =
789 SecTable.getSectionOfType<StringTableSection>(
790Link,
791"Symbol table has link index of " +Twine(Link) +
792" which is not a valid index",
793"Symbol table has link index of " +Twine(Link) +
794" which is not a string table");
795if (!Sec)
796return Sec.takeError();
797
798 setStrTab(*Sec);
799returnError::success();
800}
801
802voidSymbolTableSection::finalize() {
803uint32_t MaxLocalIndex = 0;
804for (std::unique_ptr<Symbol> &Sym :Symbols) {
805Sym->NameIndex =
806SymbolNames ==nullptr ? 0 :SymbolNames->findIndex(Sym->Name);
807if (Sym->Binding ==STB_LOCAL)
808 MaxLocalIndex = std::max(MaxLocalIndex,Sym->Index);
809 }
810// Now we need to set the Link and Info fields.
811Link =SymbolNames ==nullptr ? 0 :SymbolNames->Index;
812Info = MaxLocalIndex + 1;
813}
814
815voidSymbolTableSection::prepareForLayout() {
816// Reserve proper amount of space in section index table, so we can
817// layout sections correctly. We will fill the table with correct
818// indexes later in fillShdnxTable.
819if (SectionIndexTable)
820SectionIndexTable->reserve(Symbols.size());
821
822// Add all of our strings to SymbolNames so that SymbolNames has the right
823// size before layout is decided.
824// If the symbol names section has been removed, don't try to add strings to
825// the table.
826if (SymbolNames !=nullptr)
827for (std::unique_ptr<Symbol> &Sym :Symbols)
828SymbolNames->addString(Sym->Name);
829}
830
831voidSymbolTableSection::fillShndxTable() {
832if (SectionIndexTable ==nullptr)
833return;
834// Fill section index table with real section indexes. This function must
835// be called after assignOffsets.
836for (const std::unique_ptr<Symbol> &Sym :Symbols) {
837if (Sym->DefinedIn !=nullptr &&Sym->DefinedIn->Index >=SHN_LORESERVE)
838SectionIndexTable->addIndex(Sym->DefinedIn->Index);
839else
840SectionIndexTable->addIndex(SHN_UNDEF);
841 }
842}
843
844Expected<const Symbol *>
845SymbolTableSection::getSymbolByIndex(uint32_t Index) const{
846if (Symbols.size() <=Index)
847returncreateStringError(errc::invalid_argument,
848"invalid symbol index: " +Twine(Index));
849returnSymbols[Index].get();
850}
851
852Expected<Symbol *>SymbolTableSection::getSymbolByIndex(uint32_t Index) {
853Expected<const Symbol *>Sym =
854static_cast<constSymbolTableSection *>(this)->getSymbolByIndex(Index);
855if (!Sym)
856returnSym.takeError();
857
858returnconst_cast<Symbol *>(*Sym);
859}
860
861template <class ELFT>
862ErrorELFSectionWriter<ELFT>::visit(constSymbolTableSection &Sec) {
863 Elf_Sym *Sym =reinterpret_cast<Elf_Sym *>(Out.getBufferStart() + Sec.Offset);
864// Loop though symbols setting each entry of the symbol table.
865for (const std::unique_ptr<Symbol> &Symbol : Sec.Symbols) {
866Sym->st_name =Symbol->NameIndex;
867Sym->st_value =Symbol->Value;
868Sym->st_size =Symbol->Size;
869Sym->st_other =Symbol->Visibility;
870Sym->setBinding(Symbol->Binding);
871Sym->setType(Symbol->Type);
872Sym->st_shndx =Symbol->getShndx();
873 ++Sym;
874 }
875returnError::success();
876}
877
878ErrorSymbolTableSection::accept(SectionVisitor &Visitor) const{
879return Visitor.visit(*this);
880}
881
882ErrorSymbolTableSection::accept(MutableSectionVisitor &Visitor) {
883return Visitor.visit(*this);
884}
885
886StringRefRelocationSectionBase::getNamePrefix() const{
887switch (Type) {
888caseSHT_REL:
889return".rel";
890caseSHT_RELA:
891return".rela";
892caseSHT_CREL:
893return".crel";
894default:
895llvm_unreachable("not a relocation section");
896 }
897}
898
899ErrorRelocationSection::removeSectionReferences(
900bool AllowBrokenLinks,function_ref<bool(constSectionBase *)>ToRemove) {
901if (ToRemove(Symbols)) {
902if (!AllowBrokenLinks)
903returncreateStringError(
904llvm::errc::invalid_argument,
905"symbol table '%s' cannot be removed because it is "
906"referenced by the relocation section '%s'",
907Symbols->Name.data(), this->Name.data());
908Symbols =nullptr;
909 }
910
911for (constRelocation &R : Relocations) {
912if (!R.RelocSymbol || !R.RelocSymbol->DefinedIn ||
913 !ToRemove(R.RelocSymbol->DefinedIn))
914continue;
915returncreateStringError(llvm::errc::invalid_argument,
916"section '%s' cannot be removed: (%s+0x%" PRIx64
917") has relocation against symbol '%s'",
918 R.RelocSymbol->DefinedIn->Name.data(),
919SecToApplyRel->Name.data(), R.Offset,
920 R.RelocSymbol->Name.c_str());
921 }
922
923returnError::success();
924}
925
926template <class SymTabType>
927ErrorRelocSectionWithSymtabBase<SymTabType>::initialize(
928SectionTableRef SecTable) {
929if (Link !=SHN_UNDEF) {
930Expected<SymTabType *> Sec = SecTable.getSectionOfType<SymTabType>(
931 Link,
932"Link field value " +Twine(Link) +" in section " +Name +
933" is invalid",
934"Link field value " +Twine(Link) +" in section " +Name +
935" is not a symbol table");
936if (!Sec)
937return Sec.takeError();
938
939 setSymTab(*Sec);
940 }
941
942if (Info !=SHN_UNDEF) {
943Expected<SectionBase *> Sec =
944 SecTable.getSection(Info,"Info field value " +Twine(Info) +
945" in section " +Name +" is invalid");
946if (!Sec)
947return Sec.takeError();
948
949 setSection(*Sec);
950 }else
951 setSection(nullptr);
952
953returnError::success();
954}
955
956template <class SymTabType>
957voidRelocSectionWithSymtabBase<SymTabType>::finalize() {
958 this->Link = Symbols ? Symbols->Index : 0;
959
960if (SecToApplyRel !=nullptr)
961 this->Info = SecToApplyRel->Index;
962}
963
964template <class ELFT>
965staticvoidsetAddend(Elf_Rel_Impl<ELFT, false> &,uint64_t) {}
966
967template <class ELFT>
968staticvoidsetAddend(Elf_Rel_Impl<ELFT, true> &Rela,uint64_t Addend) {
969 Rela.r_addend = Addend;
970}
971
972template <class RelRange,class T>
973staticvoidwriteRel(const RelRange &Relocations,T *Buf,bool IsMips64EL) {
974for (constauto &Reloc : Relocations) {
975 Buf->r_offset = Reloc.Offset;
976setAddend(*Buf, Reloc.Addend);
977 Buf->setSymbolAndType(Reloc.RelocSymbol ? Reloc.RelocSymbol->Index : 0,
978 Reloc.Type, IsMips64EL);
979 ++Buf;
980 }
981}
982
983template <class ELFT>
984ErrorELFSectionWriter<ELFT>::visit(constRelocationSection &Sec) {
985uint8_t *Buf =reinterpret_cast<uint8_t *>(Out.getBufferStart()) + Sec.Offset;
986if (Sec.Type ==SHT_CREL) {
987autoContent = encodeCrel<ELFT::Is64Bits>(Sec.Relocations);
988 memcpy(Buf,Content.data(),Content.size());
989 }elseif (Sec.Type ==SHT_REL) {
990writeRel(Sec.Relocations,reinterpret_cast<Elf_Rel *>(Buf),
991 Sec.getObject().IsMips64EL);
992 }else {
993writeRel(Sec.Relocations,reinterpret_cast<Elf_Rela *>(Buf),
994 Sec.getObject().IsMips64EL);
995 }
996returnError::success();
997}
998
999ErrorRelocationSection::accept(SectionVisitor &Visitor) const{
1000return Visitor.visit(*this);
1001}
1002
1003ErrorRelocationSection::accept(MutableSectionVisitor &Visitor) {
1004return Visitor.visit(*this);
1005}
1006
1007ErrorRelocationSection::removeSymbols(
1008function_ref<bool(constSymbol &)>ToRemove) {
1009for (constRelocation &Reloc : Relocations)
1010if (Reloc.RelocSymbol &&ToRemove(*Reloc.RelocSymbol))
1011returncreateStringError(
1012llvm::errc::invalid_argument,
1013"not stripping symbol '%s' because it is named in a relocation",
1014 Reloc.RelocSymbol->Name.data());
1015returnError::success();
1016}
1017
1018voidRelocationSection::markSymbols() {
1019for (constRelocation &Reloc : Relocations)
1020if (Reloc.RelocSymbol)
1021 Reloc.RelocSymbol->Referenced =true;
1022}
1023
1024voidRelocationSection::replaceSectionReferences(
1025constDenseMap<SectionBase *, SectionBase *> &FromTo) {
1026// Update the target section if it was replaced.
1027if (SectionBase *To = FromTo.lookup(SecToApplyRel))
1028SecToApplyRel = To;
1029}
1030
1031ErrorSectionWriter::visit(constDynamicRelocationSection &Sec) {
1032llvm::copy(Sec.Contents,Out.getBufferStart() + Sec.Offset);
1033returnError::success();
1034}
1035
1036ErrorDynamicRelocationSection::accept(SectionVisitor &Visitor) const{
1037return Visitor.visit(*this);
1038}
1039
1040ErrorDynamicRelocationSection::accept(MutableSectionVisitor &Visitor) {
1041return Visitor.visit(*this);
1042}
1043
1044ErrorDynamicRelocationSection::removeSectionReferences(
1045bool AllowBrokenLinks,function_ref<bool(constSectionBase *)>ToRemove) {
1046if (ToRemove(Symbols)) {
1047if (!AllowBrokenLinks)
1048returncreateStringError(
1049llvm::errc::invalid_argument,
1050"symbol table '%s' cannot be removed because it is "
1051"referenced by the relocation section '%s'",
1052Symbols->Name.data(), this->Name.data());
1053Symbols =nullptr;
1054 }
1055
1056// SecToApplyRel contains a section referenced by sh_info field. It keeps
1057// a section to which the relocation section applies. When we remove any
1058// sections we also remove their relocation sections. Since we do that much
1059// earlier, this assert should never be triggered.
1060assert(!SecToApplyRel || !ToRemove(SecToApplyRel));
1061returnError::success();
1062}
1063
1064ErrorSection::removeSectionReferences(
1065bool AllowBrokenDependency,
1066function_ref<bool(constSectionBase *)>ToRemove) {
1067if (ToRemove(LinkSection)) {
1068if (!AllowBrokenDependency)
1069returncreateStringError(llvm::errc::invalid_argument,
1070"section '%s' cannot be removed because it is "
1071"referenced by the section '%s'",
1072 LinkSection->Name.data(), this->Name.data());
1073 LinkSection =nullptr;
1074 }
1075returnError::success();
1076}
1077
1078voidGroupSection::finalize() {
1079 this->Info = Sym ? Sym->Index : 0;
1080 this->Link = SymTab ? SymTab->Index : 0;
1081// Linker deduplication for GRP_COMDAT is based on Sym->Name. The local/global
1082// status is not part of the equation. If Sym is localized, the intention is
1083// likely to make the group fully localized. Drop GRP_COMDAT to suppress
1084// deduplication. See https://groups.google.com/g/generic-abi/c/2X6mR-s2zoc
1085if ((FlagWord &GRP_COMDAT) && Sym && Sym->Binding ==STB_LOCAL)
1086 this->FlagWord &= ~GRP_COMDAT;
1087}
1088
1089ErrorGroupSection::removeSectionReferences(
1090bool AllowBrokenLinks,function_ref<bool(constSectionBase *)>ToRemove) {
1091if (ToRemove(SymTab)) {
1092if (!AllowBrokenLinks)
1093returncreateStringError(
1094llvm::errc::invalid_argument,
1095"section '.symtab' cannot be removed because it is "
1096"referenced by the group section '%s'",
1097 this->Name.data());
1098 SymTab =nullptr;
1099 Sym =nullptr;
1100 }
1101llvm::erase_if(GroupMembers,ToRemove);
1102returnError::success();
1103}
1104
1105ErrorGroupSection::removeSymbols(function_ref<bool(constSymbol &)>ToRemove) {
1106if (ToRemove(*Sym))
1107returncreateStringError(llvm::errc::invalid_argument,
1108"symbol '%s' cannot be removed because it is "
1109"referenced by the section '%s[%d]'",
1110 Sym->Name.data(), this->Name.data(), this->Index);
1111returnError::success();
1112}
1113
1114voidGroupSection::markSymbols() {
1115if (Sym)
1116 Sym->Referenced =true;
1117}
1118
1119voidGroupSection::replaceSectionReferences(
1120constDenseMap<SectionBase *, SectionBase *> &FromTo) {
1121for (SectionBase *&Sec : GroupMembers)
1122if (SectionBase *To = FromTo.lookup(Sec))
1123 Sec = To;
1124}
1125
1126voidGroupSection::onRemove() {
1127// As the header section of the group is removed, drop the Group flag in its
1128// former members.
1129for (SectionBase *Sec : GroupMembers)
1130 Sec->Flags &= ~SHF_GROUP;
1131}
1132
1133ErrorSection::initialize(SectionTableRef SecTable) {
1134if (Link ==ELF::SHN_UNDEF)
1135returnError::success();
1136
1137Expected<SectionBase *> Sec =
1138 SecTable.getSection(Link,"Link field value " +Twine(Link) +
1139" in section " +Name +" is invalid");
1140if (!Sec)
1141return Sec.takeError();
1142
1143 LinkSection = *Sec;
1144
1145if (LinkSection->Type ==ELF::SHT_SYMTAB) {
1146 HasSymTabLink =true;
1147 LinkSection =nullptr;
1148 }
1149
1150returnError::success();
1151}
1152
1153voidSection::finalize() { this->Link = LinkSection ? LinkSection->Index : 0; }
1154
1155void GnuDebugLinkSection::init(StringRefFile) {
1156 FileName =sys::path::filename(File);
1157// The format for the .gnu_debuglink starts with the file name and is
1158// followed by a null terminator and then the CRC32 of the file. The CRC32
1159// should be 4 byte aligned. So we add the FileName size, a 1 for the null
1160// byte, and then finally push the size to alignment and add 4.
1161Size =alignTo(FileName.size() + 1, 4) + 4;
1162// The CRC32 will only be aligned if we align the whole section.
1163Align = 4;
1164Type =OriginalType =ELF::SHT_PROGBITS;
1165Name =".gnu_debuglink";
1166// For sections not found in segments, OriginalOffset is only used to
1167// establish the order that sections should go in. By using the maximum
1168// possible offset we cause this section to wind up at the end.
1169OriginalOffset = std::numeric_limits<uint64_t>::max();
1170}
1171
1172GnuDebugLinkSection::GnuDebugLinkSection(StringRefFile,
1173uint32_t PrecomputedCRC)
1174 : FileName(File), CRC32(PrecomputedCRC) {
1175 init(File);
1176}
1177
1178template <class ELFT>
1179ErrorELFSectionWriter<ELFT>::visit(constGnuDebugLinkSection &Sec) {
1180unsignedchar *Buf =
1181reinterpret_cast<uint8_t *>(Out.getBufferStart()) + Sec.Offset;
1182 Elf_Word *CRC =
1183reinterpret_cast<Elf_Word *>(Buf + Sec.Size -sizeof(Elf_Word));
1184 *CRC = Sec.CRC32;
1185llvm::copy(Sec.FileName, Buf);
1186returnError::success();
1187}
1188
1189ErrorGnuDebugLinkSection::accept(SectionVisitor &Visitor) const{
1190return Visitor.visit(*this);
1191}
1192
1193ErrorGnuDebugLinkSection::accept(MutableSectionVisitor &Visitor) {
1194return Visitor.visit(*this);
1195}
1196
1197template <class ELFT>
1198ErrorELFSectionWriter<ELFT>::visit(constGroupSection &Sec) {
1199ELF::Elf32_Word *Buf =
1200reinterpret_cast<ELF::Elf32_Word *>(Out.getBufferStart() + Sec.Offset);
1201 endian::write32<ELFT::Endianness>(Buf++, Sec.FlagWord);
1202for (SectionBase *S : Sec.GroupMembers)
1203 endian::write32<ELFT::Endianness>(Buf++, S->Index);
1204returnError::success();
1205}
1206
1207ErrorGroupSection::accept(SectionVisitor &Visitor) const{
1208return Visitor.visit(*this);
1209}
1210
1211ErrorGroupSection::accept(MutableSectionVisitor &Visitor) {
1212return Visitor.visit(*this);
1213}
1214
1215// Returns true IFF a section is wholly inside the range of a segment
1216staticboolsectionWithinSegment(constSectionBase &Sec,constSegment &Seg) {
1217// If a section is empty it should be treated like it has a size of 1. This is
1218// to clarify the case when an empty section lies on a boundary between two
1219// segments and ensures that the section "belongs" to the second segment and
1220// not the first.
1221uint64_t SecSize = Sec.Size ? Sec.Size : 1;
1222
1223// Ignore just added sections.
1224if (Sec.OriginalOffset == std::numeric_limits<uint64_t>::max())
1225returnfalse;
1226
1227if (Sec.Type ==SHT_NOBITS) {
1228if (!(Sec.Flags &SHF_ALLOC))
1229returnfalse;
1230
1231bool SectionIsTLS = Sec.Flags &SHF_TLS;
1232bool SegmentIsTLS = Seg.Type ==PT_TLS;
1233if (SectionIsTLS != SegmentIsTLS)
1234returnfalse;
1235
1236return Seg.VAddr <= Sec.Addr &&
1237 Seg.VAddr + Seg.MemSize >= Sec.Addr + SecSize;
1238 }
1239
1240return Seg.Offset <= Sec.OriginalOffset &&
1241 Seg.Offset + Seg.FileSize >= Sec.OriginalOffset + SecSize;
1242}
1243
1244// Returns true IFF a segment's original offset is inside of another segment's
1245// range.
1246staticboolsegmentOverlapsSegment(constSegment &Child,
1247constSegment &Parent) {
1248
1249return Parent.OriginalOffset <= Child.OriginalOffset &&
1250 Parent.OriginalOffset + Parent.FileSize > Child.OriginalOffset;
1251}
1252
1253staticboolcompareSegmentsByOffset(constSegment *A,constSegment *B) {
1254// Any segment without a parent segment should come before a segment
1255// that has a parent segment.
1256if (A->OriginalOffset <B->OriginalOffset)
1257returntrue;
1258if (A->OriginalOffset >B->OriginalOffset)
1259returnfalse;
1260// If alignments are different, the one with a smaller alignment cannot be the
1261// parent; otherwise, layoutSegments will not respect the larger alignment
1262// requirement. This rule ensures that PT_LOAD/PT_INTERP/PT_GNU_RELRO/PT_TLS
1263// segments at the same offset will be aligned correctly.
1264if (A->Align !=B->Align)
1265returnA->Align >B->Align;
1266returnA->Index <B->Index;
1267}
1268
1269voidBasicELFBuilder::initFileHeader() {
1270Obj->Flags = 0x0;
1271Obj->Type =ET_REL;
1272Obj->OSABI =ELFOSABI_NONE;
1273Obj->ABIVersion = 0;
1274Obj->Entry = 0x0;
1275Obj->Machine =EM_NONE;
1276Obj->Version = 1;
1277}
1278
1279voidBasicELFBuilder::initHeaderSegment() {Obj->ElfHdrSegment.Index = 0; }
1280
1281StringTableSection *BasicELFBuilder::addStrTab() {
1282auto &StrTab =Obj->addSection<StringTableSection>();
1283 StrTab.Name =".strtab";
1284
1285Obj->SectionNames = &StrTab;
1286return &StrTab;
1287}
1288
1289SymbolTableSection *BasicELFBuilder::addSymTab(StringTableSection *StrTab) {
1290auto &SymTab =Obj->addSection<SymbolTableSection>();
1291
1292 SymTab.Name =".symtab";
1293 SymTab.Link = StrTab->Index;
1294
1295// The symbol table always needs a null symbol
1296 SymTab.addSymbol("", 0, 0,nullptr, 0, 0, 0, 0);
1297
1298Obj->SymbolTable = &SymTab;
1299return &SymTab;
1300}
1301
1302ErrorBasicELFBuilder::initSections() {
1303for (SectionBase &Sec :Obj->sections())
1304if (Error Err = Sec.initialize(Obj->sections()))
1305return Err;
1306
1307returnError::success();
1308}
1309
1310void BinaryELFBuilder::addData(SymbolTableSection *SymTab) {
1311autoData =ArrayRef<uint8_t>(
1312reinterpret_cast<constuint8_t *>(MemBuf->getBufferStart()),
1313 MemBuf->getBufferSize());
1314auto &DataSection =Obj->addSection<Section>(Data);
1315 DataSection.Name =".data";
1316 DataSection.Type =ELF::SHT_PROGBITS;
1317 DataSection.Size =Data.size();
1318 DataSection.Flags =ELF::SHF_ALLOC |ELF::SHF_WRITE;
1319
1320 std::string SanitizedFilename = MemBuf->getBufferIdentifier().str();
1321 std::replace_if(
1322 std::begin(SanitizedFilename), std::end(SanitizedFilename),
1323 [](charC) {return !isAlnum(C); },'_');
1324Twine Prefix =Twine("_binary_") + SanitizedFilename;
1325
1326 SymTab->addSymbol(Prefix +"_start",STB_GLOBAL,STT_NOTYPE, &DataSection,
1327/*Value=*/0, NewSymbolVisibility, 0, 0);
1328 SymTab->addSymbol(Prefix +"_end",STB_GLOBAL,STT_NOTYPE, &DataSection,
1329/*Value=*/DataSection.Size, NewSymbolVisibility, 0, 0);
1330 SymTab->addSymbol(Prefix +"_size",STB_GLOBAL,STT_NOTYPE,nullptr,
1331/*Value=*/DataSection.Size, NewSymbolVisibility,SHN_ABS,
1332 0);
1333}
1334
1335Expected<std::unique_ptr<Object>>BinaryELFBuilder::build() {
1336initFileHeader();
1337initHeaderSegment();
1338
1339SymbolTableSection *SymTab =addSymTab(addStrTab());
1340if (Error Err =initSections())
1341return std::move(Err);
1342 addData(SymTab);
1343
1344return std::move(Obj);
1345}
1346
1347// Adds sections from IHEX data file. Data should have been
1348// fully validated by this time.
1349void IHexELFBuilder::addDataSections() {
1350OwnedDataSection *Section =nullptr;
1351uint64_t SegmentAddr = 0, BaseAddr = 0;
1352uint32_t SecNo = 1;
1353
1354for (constIHexRecord &R : Records) {
1355uint64_t RecAddr;
1356switch (R.Type) {
1357caseIHexRecord::Data:
1358// Ignore empty data records
1359if (R.HexData.empty())
1360continue;
1361 RecAddr = R.Addr + SegmentAddr + BaseAddr;
1362if (!Section ||Section->Addr +Section->Size != RecAddr) {
1363// OriginalOffset field is only used to sort sections before layout, so
1364// instead of keeping track of real offsets in IHEX file, and as
1365// layoutSections() and layoutSectionsForOnlyKeepDebug() use
1366// llvm::stable_sort(), we can just set it to a constant (zero).
1367Section = &Obj->addSection<OwnedDataSection>(
1368".sec" + std::to_string(SecNo), RecAddr,
1369ELF::SHF_ALLOC |ELF::SHF_WRITE, 0);
1370 SecNo++;
1371 }
1372Section->appendHexData(R.HexData);
1373break;
1374caseIHexRecord::EndOfFile:
1375break;
1376caseIHexRecord::SegmentAddr:
1377// 20-bit segment address.
1378 SegmentAddr = checkedGetHex<uint16_t>(R.HexData) << 4;
1379break;
1380caseIHexRecord::StartAddr80x86:
1381caseIHexRecord::StartAddr:
1382Obj->Entry = checkedGetHex<uint32_t>(R.HexData);
1383assert(Obj->Entry <= 0xFFFFFU);
1384break;
1385caseIHexRecord::ExtendedAddr:
1386// 16-31 bits of linear base address
1387 BaseAddr = checkedGetHex<uint16_t>(R.HexData) << 16;
1388break;
1389default:
1390llvm_unreachable("unknown record type");
1391 }
1392 }
1393}
1394
1395Expected<std::unique_ptr<Object>>IHexELFBuilder::build() {
1396initFileHeader();
1397initHeaderSegment();
1398StringTableSection *StrTab =addStrTab();
1399addSymTab(StrTab);
1400if (Error Err =initSections())
1401return std::move(Err);
1402 addDataSections();
1403
1404return std::move(Obj);
1405}
1406
1407template <class ELFT>
1408ELFBuilder<ELFT>::ELFBuilder(constELFObjectFile<ELFT> &ElfObj,Object &Obj,
1409 std::optional<StringRef> ExtractPartition)
1410 : ElfFile(ElfObj.getELFFile()), Obj(Obj),
1411 ExtractPartition(ExtractPartition) {
1412 Obj.IsMips64EL = ElfFile.isMips64EL();
1413}
1414
1415template <class ELFT>voidELFBuilder<ELFT>::setParentSegment(Segment &Child) {
1416for (Segment &Parent : Obj.segments()) {
1417// Every segment will overlap with itself but we don't want a segment to
1418// be its own parent so we avoid that situation.
1419if (&Child != &Parent &&segmentOverlapsSegment(Child, Parent)) {
1420// We want a canonical "most parental" segment but this requires
1421// inspecting the ParentSegment.
1422if (compareSegmentsByOffset(&Parent, &Child))
1423if (Child.ParentSegment ==nullptr ||
1424compareSegmentsByOffset(&Parent, Child.ParentSegment)) {
1425 Child.ParentSegment = &Parent;
1426 }
1427 }
1428 }
1429}
1430
1431template <class ELFT>ErrorELFBuilder<ELFT>::findEhdrOffset() {
1432if (!ExtractPartition)
1433returnError::success();
1434
1435for (constSectionBase &Sec : Obj.sections()) {
1436if (Sec.Type ==SHT_LLVM_PART_EHDR && Sec.Name == *ExtractPartition) {
1437 EhdrOffset = Sec.Offset;
1438returnError::success();
1439 }
1440 }
1441returncreateStringError(errc::invalid_argument,
1442"could not find partition named '" +
1443 *ExtractPartition +"'");
1444}
1445
1446template <class ELFT>
1447ErrorELFBuilder<ELFT>::readProgramHeaders(constELFFile<ELFT> &HeadersFile) {
1448uint32_tIndex = 0;
1449
1450Expected<typename ELFFile<ELFT>::Elf_Phdr_Range> Headers =
1451 HeadersFile.program_headers();
1452if (!Headers)
1453return Headers.takeError();
1454
1455for (consttypenameELFFile<ELFT>::Elf_Phdr &Phdr : *Headers) {
1456if (Phdr.p_offset + Phdr.p_filesz > HeadersFile.getBufSize())
1457returncreateStringError(
1458errc::invalid_argument,
1459"program header with offset 0x" +Twine::utohexstr(Phdr.p_offset) +
1460" and file size 0x" +Twine::utohexstr(Phdr.p_filesz) +
1461" goes past the end of the file");
1462
1463ArrayRef<uint8_t>Data{HeadersFile.base() + Phdr.p_offset,
1464 (size_t)Phdr.p_filesz};
1465Segment &Seg = Obj.addSegment(Data);
1466 Seg.Type = Phdr.p_type;
1467 Seg.Flags = Phdr.p_flags;
1468 Seg.OriginalOffset = Phdr.p_offset + EhdrOffset;
1469 Seg.Offset = Phdr.p_offset + EhdrOffset;
1470 Seg.VAddr = Phdr.p_vaddr;
1471 Seg.PAddr = Phdr.p_paddr;
1472 Seg.FileSize = Phdr.p_filesz;
1473 Seg.MemSize = Phdr.p_memsz;
1474 Seg.Align = Phdr.p_align;
1475 Seg.Index =Index++;
1476for (SectionBase &Sec : Obj.sections())
1477if (sectionWithinSegment(Sec, Seg)) {
1478 Seg.addSection(&Sec);
1479if (!Sec.ParentSegment || Sec.ParentSegment->Offset > Seg.Offset)
1480 Sec.ParentSegment = &Seg;
1481 }
1482 }
1483
1484auto &ElfHdr = Obj.ElfHdrSegment;
1485 ElfHdr.Index =Index++;
1486 ElfHdr.OriginalOffset = ElfHdr.Offset = EhdrOffset;
1487
1488consttypename ELFT::Ehdr &Ehdr = HeadersFile.getHeader();
1489auto &PrHdr = Obj.ProgramHdrSegment;
1490 PrHdr.Type =PT_PHDR;
1491 PrHdr.Flags = 0;
1492// The spec requires us to have p_vaddr % p_align == p_offset % p_align.
1493// Whereas this works automatically for ElfHdr, here OriginalOffset is
1494// always non-zero and to ensure the equation we assign the same value to
1495// VAddr as well.
1496 PrHdr.OriginalOffset = PrHdr.Offset = PrHdr.VAddr = EhdrOffset + Ehdr.e_phoff;
1497 PrHdr.PAddr = 0;
1498 PrHdr.FileSize = PrHdr.MemSize = Ehdr.e_phentsize * Ehdr.e_phnum;
1499// The spec requires us to naturally align all the fields.
1500 PrHdr.Align =sizeof(Elf_Addr);
1501 PrHdr.Index =Index++;
1502
1503// Now we do an O(n^2) loop through the segments in order to match up
1504// segments.
1505for (Segment &Child : Obj.segments())
1506 setParentSegment(Child);
1507 setParentSegment(ElfHdr);
1508 setParentSegment(PrHdr);
1509
1510returnError::success();
1511}
1512
1513template <class ELFT>
1514ErrorELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {
1515if (GroupSec->Align %sizeof(ELF::Elf32_Word) != 0)
1516returncreateStringError(errc::invalid_argument,
1517"invalid alignment " +Twine(GroupSec->Align) +
1518" of group section '" + GroupSec->Name +"'");
1519SectionTableRef SecTable = Obj.sections();
1520if (GroupSec->Link !=SHN_UNDEF) {
1521auto SymTab = SecTable.template getSectionOfType<SymbolTableSection>(
1522 GroupSec->Link,
1523"link field value '" +Twine(GroupSec->Link) +"' in section '" +
1524 GroupSec->Name +"' is invalid",
1525"link field value '" +Twine(GroupSec->Link) +"' in section '" +
1526 GroupSec->Name +"' is not a symbol table");
1527if (!SymTab)
1528return SymTab.takeError();
1529
1530Expected<Symbol *>Sym = (*SymTab)->getSymbolByIndex(GroupSec->Info);
1531if (!Sym)
1532returncreateStringError(errc::invalid_argument,
1533"info field value '" +Twine(GroupSec->Info) +
1534"' in section '" + GroupSec->Name +
1535"' is not a valid symbol index");
1536 GroupSec->setSymTab(*SymTab);
1537 GroupSec->setSymbol(*Sym);
1538 }
1539if (GroupSec->Contents.size() %sizeof(ELF::Elf32_Word) ||
1540 GroupSec->Contents.empty())
1541returncreateStringError(errc::invalid_argument,
1542"the content of the section " + GroupSec->Name +
1543" is malformed");
1544constELF::Elf32_Word *Word =
1545reinterpret_cast<constELF::Elf32_Word *>(GroupSec->Contents.data());
1546constELF::Elf32_Word *End =
1547Word + GroupSec->Contents.size() /sizeof(ELF::Elf32_Word);
1548 GroupSec->setFlagWord(endian::read32<ELFT::Endianness>(Word++));
1549for (;Word !=End; ++Word) {
1550uint32_tIndex = support::endian::read32<ELFT::Endianness>(Word);
1551Expected<SectionBase *> Sec = SecTable.getSection(
1552 Index,"group member index " +Twine(Index) +" in section '" +
1553 GroupSec->Name +"' is invalid");
1554if (!Sec)
1555return Sec.takeError();
1556
1557 GroupSec->addMember(*Sec);
1558 }
1559
1560returnError::success();
1561}
1562
1563template <class ELFT>
1564ErrorELFBuilder<ELFT>::initSymbolTable(SymbolTableSection *SymTab) {
1565Expected<const Elf_Shdr *>Shdr = ElfFile.getSection(SymTab->Index);
1566if (!Shdr)
1567returnShdr.takeError();
1568
1569Expected<StringRef> StrTabData = ElfFile.getStringTableForSymtab(**Shdr);
1570if (!StrTabData)
1571return StrTabData.takeError();
1572
1573ArrayRef<Elf_Word> ShndxData;
1574
1575Expected<typename ELFFile<ELFT>::Elf_Sym_Range> Symbols =
1576 ElfFile.symbols(*Shdr);
1577if (!Symbols)
1578return Symbols.takeError();
1579
1580for (consttypenameELFFile<ELFT>::Elf_Sym &Sym : *Symbols) {
1581SectionBase *DefSection =nullptr;
1582
1583Expected<StringRef>Name =Sym.getName(*StrTabData);
1584if (!Name)
1585returnName.takeError();
1586
1587if (Sym.st_shndx ==SHN_XINDEX) {
1588if (SymTab->getShndxTable() ==nullptr)
1589returncreateStringError(errc::invalid_argument,
1590"symbol '" + *Name +
1591"' has index SHN_XINDEX but no "
1592"SHT_SYMTAB_SHNDX section exists");
1593if (ShndxData.data() ==nullptr) {
1594Expected<const Elf_Shdr *> ShndxSec =
1595 ElfFile.getSection(SymTab->getShndxTable()->Index);
1596if (!ShndxSec)
1597return ShndxSec.takeError();
1598
1599Expected<ArrayRef<Elf_Word>>Data =
1600 ElfFile.template getSectionContentsAsArray<Elf_Word>(**ShndxSec);
1601if (!Data)
1602returnData.takeError();
1603
1604 ShndxData = *Data;
1605if (ShndxData.size() != Symbols->size())
1606returncreateStringError(
1607errc::invalid_argument,
1608"symbol section index table does not have the same number of "
1609"entries as the symbol table");
1610 }
1611 Elf_WordIndex = ShndxData[&Sym - Symbols->begin()];
1612Expected<SectionBase *> Sec = Obj.sections().getSection(
1613 Index,
1614"symbol '" + *Name +"' has invalid section index " +Twine(Index));
1615if (!Sec)
1616return Sec.takeError();
1617
1618 DefSection = *Sec;
1619 }elseif (Sym.st_shndx >=SHN_LORESERVE) {
1620if (!isValidReservedSectionIndex(Sym.st_shndx, Obj.Machine)) {
1621returncreateStringError(
1622errc::invalid_argument,
1623"symbol '" + *Name +
1624"' has unsupported value greater than or equal "
1625"to SHN_LORESERVE: " +
1626Twine(Sym.st_shndx));
1627 }
1628 }elseif (Sym.st_shndx !=SHN_UNDEF) {
1629Expected<SectionBase *> Sec = Obj.sections().getSection(
1630Sym.st_shndx,"symbol '" + *Name +
1631"' is defined has invalid section index " +
1632Twine(Sym.st_shndx));
1633if (!Sec)
1634return Sec.takeError();
1635
1636 DefSection = *Sec;
1637 }
1638
1639 SymTab->addSymbol(*Name,Sym.getBinding(),Sym.getType(), DefSection,
1640Sym.getValue(),Sym.st_other,Sym.st_shndx,Sym.st_size);
1641 }
1642
1643returnError::success();
1644}
1645
1646template <class ELFT>
1647staticvoidgetAddend(uint64_t &,constElf_Rel_Impl<ELFT, false> &) {}
1648
1649template <class ELFT>
1650staticvoidgetAddend(uint64_t &ToSet,constElf_Rel_Impl<ELFT, true> &Rela) {
1651 ToSet = Rela.r_addend;
1652}
1653
1654template <class T>
1655staticErrorinitRelocations(RelocationSection *Relocs,T RelRange) {
1656for (constauto &Rel : RelRange) {
1657Relocation ToAdd;
1658 ToAdd.Offset = Rel.r_offset;
1659getAddend(ToAdd.Addend, Rel);
1660 ToAdd.Type = Rel.getType(Relocs->getObject().IsMips64EL);
1661
1662if (uint32_tSym = Rel.getSymbol(Relocs->getObject().IsMips64EL)) {
1663if (!Relocs->getObject().SymbolTable)
1664returncreateStringError(
1665errc::invalid_argument,
1666"'" + Relocs->Name +"': relocation references symbol with index " +
1667Twine(Sym) +", but there is no symbol table");
1668Expected<Symbol *> SymByIndex =
1669 Relocs->getObject().SymbolTable->getSymbolByIndex(Sym);
1670if (!SymByIndex)
1671return SymByIndex.takeError();
1672
1673 ToAdd.RelocSymbol = *SymByIndex;
1674 }
1675
1676 Relocs->addRelocation(ToAdd);
1677 }
1678
1679returnError::success();
1680}
1681
1682Expected<SectionBase *>SectionTableRef::getSection(uint32_t Index,
1683Twine ErrMsg) {
1684if (Index ==SHN_UNDEF || Index > Sections.size())
1685returncreateStringError(errc::invalid_argument, ErrMsg);
1686return Sections[Index - 1].get();
1687}
1688
1689template <class T>
1690Expected<T *>SectionTableRef::getSectionOfType(uint32_t Index,
1691Twine IndexErrMsg,
1692Twine TypeErrMsg) {
1693Expected<SectionBase *> BaseSec =getSection(Index, IndexErrMsg);
1694if (!BaseSec)
1695return BaseSec.takeError();
1696
1697if (T *Sec = dyn_cast<T>(*BaseSec))
1698return Sec;
1699
1700returncreateStringError(errc::invalid_argument, TypeErrMsg);
1701}
1702
1703template <class ELFT>
1704Expected<SectionBase &>ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
1705switch (Shdr.sh_type) {
1706caseSHT_REL:
1707caseSHT_RELA:
1708caseSHT_CREL:
1709if (Shdr.sh_flags &SHF_ALLOC) {
1710if (Expected<ArrayRef<uint8_t>>Data = ElfFile.getSectionContents(Shdr))
1711return Obj.addSection<DynamicRelocationSection>(*Data);
1712else
1713returnData.takeError();
1714 }
1715return Obj.addSection<RelocationSection>(Obj);
1716caseSHT_STRTAB:
1717// If a string table is allocated we don't want to mess with it. That would
1718// mean altering the memory image. There are no special link types or
1719// anything so we can just use a Section.
1720if (Shdr.sh_flags &SHF_ALLOC) {
1721if (Expected<ArrayRef<uint8_t>>Data = ElfFile.getSectionContents(Shdr))
1722return Obj.addSection<Section>(*Data);
1723else
1724returnData.takeError();
1725 }
1726return Obj.addSection<StringTableSection>();
1727caseSHT_HASH:
1728caseSHT_GNU_HASH:
1729// Hash tables should refer to SHT_DYNSYM which we're not going to change.
1730// Because of this we don't need to mess with the hash tables either.
1731if (Expected<ArrayRef<uint8_t>>Data = ElfFile.getSectionContents(Shdr))
1732return Obj.addSection<Section>(*Data);
1733else
1734returnData.takeError();
1735caseSHT_GROUP:
1736if (Expected<ArrayRef<uint8_t>>Data = ElfFile.getSectionContents(Shdr))
1737return Obj.addSection<GroupSection>(*Data);
1738else
1739returnData.takeError();
1740caseSHT_DYNSYM:
1741if (Expected<ArrayRef<uint8_t>>Data = ElfFile.getSectionContents(Shdr))
1742return Obj.addSection<DynamicSymbolTableSection>(*Data);
1743else
1744returnData.takeError();
1745caseSHT_DYNAMIC:
1746if (Expected<ArrayRef<uint8_t>>Data = ElfFile.getSectionContents(Shdr))
1747return Obj.addSection<DynamicSection>(*Data);
1748else
1749returnData.takeError();
1750caseSHT_SYMTAB: {
1751// Multiple SHT_SYMTAB sections are forbidden by the ELF gABI.
1752if (Obj.SymbolTable !=nullptr)
1753returncreateStringError(llvm::errc::invalid_argument,
1754"found multiple SHT_SYMTAB sections");
1755auto &SymTab = Obj.addSection<SymbolTableSection>();
1756 Obj.SymbolTable = &SymTab;
1757return SymTab;
1758 }
1759caseSHT_SYMTAB_SHNDX: {
1760auto &ShndxSection = Obj.addSection<SectionIndexSection>();
1761 Obj.SectionIndexTable = &ShndxSection;
1762return ShndxSection;
1763 }
1764caseSHT_NOBITS:
1765return Obj.addSection<Section>(ArrayRef<uint8_t>());
1766default: {
1767Expected<ArrayRef<uint8_t>>Data = ElfFile.getSectionContents(Shdr);
1768if (!Data)
1769returnData.takeError();
1770
1771Expected<StringRef>Name = ElfFile.getSectionName(Shdr);
1772if (!Name)
1773returnName.takeError();
1774
1775if (!(Shdr.sh_flags &ELF::SHF_COMPRESSED))
1776return Obj.addSection<Section>(*Data);
1777auto *Chdr =reinterpret_cast<constElf_Chdr_Impl<ELFT> *>(Data->data());
1778return Obj.addSection<CompressedSection>(CompressedSection(
1779 *Data, Chdr->ch_type, Chdr->ch_size, Chdr->ch_addralign));
1780 }
1781 }
1782}
1783
1784template <class ELFT>ErrorELFBuilder<ELFT>::readSectionHeaders() {
1785uint32_tIndex = 0;
1786Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
1787 ElfFile.sections();
1788if (!Sections)
1789return Sections.takeError();
1790
1791for (consttypenameELFFile<ELFT>::Elf_Shdr &Shdr : *Sections) {
1792if (Index == 0) {
1793 ++Index;
1794continue;
1795 }
1796Expected<SectionBase &> Sec = makeSection(Shdr);
1797if (!Sec)
1798return Sec.takeError();
1799
1800Expected<StringRef> SecName = ElfFile.getSectionName(Shdr);
1801if (!SecName)
1802return SecName.takeError();
1803 Sec->Name = SecName->str();
1804 Sec->Type = Sec->OriginalType =Shdr.sh_type;
1805 Sec->Flags = Sec->OriginalFlags =Shdr.sh_flags;
1806 Sec->Addr =Shdr.sh_addr;
1807 Sec->Offset =Shdr.sh_offset;
1808 Sec->OriginalOffset =Shdr.sh_offset;
1809 Sec->Size =Shdr.sh_size;
1810 Sec->Link =Shdr.sh_link;
1811 Sec->Info =Shdr.sh_info;
1812 Sec->Align =Shdr.sh_addralign;
1813 Sec->EntrySize =Shdr.sh_entsize;
1814 Sec->Index =Index++;
1815 Sec->OriginalIndex = Sec->Index;
1816 Sec->OriginalData =ArrayRef<uint8_t>(
1817 ElfFile.base() +Shdr.sh_offset,
1818 (Shdr.sh_type ==SHT_NOBITS) ? (size_t)0 :Shdr.sh_size);
1819 }
1820
1821returnError::success();
1822}
1823
1824template <class ELFT>ErrorELFBuilder<ELFT>::readSections(bool EnsureSymtab) {
1825uint32_t ShstrIndex = ElfFile.getHeader().e_shstrndx;
1826if (ShstrIndex ==SHN_XINDEX) {
1827Expected<const Elf_Shdr *> Sec = ElfFile.getSection(0);
1828if (!Sec)
1829return Sec.takeError();
1830
1831 ShstrIndex = (*Sec)->sh_link;
1832 }
1833
1834if (ShstrIndex ==SHN_UNDEF)
1835 Obj.HadShdrs =false;
1836else {
1837Expected<StringTableSection *> Sec =
1838 Obj.sections().template getSectionOfType<StringTableSection>(
1839 ShstrIndex,
1840"e_shstrndx field value " +Twine(ShstrIndex) +" in elf header " +
1841" is invalid",
1842"e_shstrndx field value " +Twine(ShstrIndex) +" in elf header " +
1843" does not reference a string table");
1844if (!Sec)
1845return Sec.takeError();
1846
1847 Obj.SectionNames = *Sec;
1848 }
1849
1850// If a section index table exists we'll need to initialize it before we
1851// initialize the symbol table because the symbol table might need to
1852// reference it.
1853if (Obj.SectionIndexTable)
1854if (Error Err = Obj.SectionIndexTable->initialize(Obj.sections()))
1855return Err;
1856
1857// Now that all of the sections have been added we can fill out some extra
1858// details about symbol tables. We need the symbol table filled out before
1859// any relocations.
1860if (Obj.SymbolTable) {
1861if (Error Err = Obj.SymbolTable->initialize(Obj.sections()))
1862return Err;
1863if (Error Err = initSymbolTable(Obj.SymbolTable))
1864return Err;
1865 }elseif (EnsureSymtab) {
1866if (Error Err = Obj.addNewSymbolTable())
1867return Err;
1868 }
1869
1870// Now that all sections and symbols have been added we can add
1871// relocations that reference symbols and set the link and info fields for
1872// relocation sections.
1873for (SectionBase &Sec : Obj.sections()) {
1874if (&Sec == Obj.SymbolTable)
1875continue;
1876if (Error Err = Sec.initialize(Obj.sections()))
1877return Err;
1878if (auto RelSec = dyn_cast<RelocationSection>(&Sec)) {
1879Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
1880 ElfFile.sections();
1881if (!Sections)
1882return Sections.takeError();
1883
1884consttypenameELFFile<ELFT>::Elf_Shdr *Shdr =
1885 Sections->begin() + RelSec->Index;
1886if (RelSec->Type ==SHT_CREL) {
1887auto RelsOrRelas = ElfFile.crels(*Shdr);
1888if (!RelsOrRelas)
1889return RelsOrRelas.takeError();
1890if (Error Err =initRelocations(RelSec, RelsOrRelas->first))
1891return Err;
1892if (Error Err =initRelocations(RelSec, RelsOrRelas->second))
1893return Err;
1894 }elseif (RelSec->Type ==SHT_REL) {
1895Expected<typename ELFFile<ELFT>::Elf_Rel_Range> Rels =
1896 ElfFile.rels(*Shdr);
1897if (!Rels)
1898return Rels.takeError();
1899
1900if (Error Err =initRelocations(RelSec, *Rels))
1901return Err;
1902 }else {
1903Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =
1904 ElfFile.relas(*Shdr);
1905if (!Relas)
1906return Relas.takeError();
1907
1908if (Error Err =initRelocations(RelSec, *Relas))
1909return Err;
1910 }
1911 }elseif (auto GroupSec = dyn_cast<GroupSection>(&Sec)) {
1912if (Error Err = initGroupSection(GroupSec))
1913return Err;
1914 }
1915 }
1916
1917returnError::success();
1918}
1919
1920template <class ELFT>ErrorELFBuilder<ELFT>::build(bool EnsureSymtab) {
1921if (Error E = readSectionHeaders())
1922return E;
1923if (Error E = findEhdrOffset())
1924return E;
1925
1926// The ELFFile whose ELF headers and program headers are copied into the
1927// output file. Normally the same as ElfFile, but if we're extracting a
1928// loadable partition it will point to the partition's headers.
1929Expected<ELFFile<ELFT>> HeadersFile =ELFFile<ELFT>::create(toStringRef(
1930 {ElfFile.base() + EhdrOffset, ElfFile.getBufSize() - EhdrOffset}));
1931if (!HeadersFile)
1932return HeadersFile.takeError();
1933
1934consttypenameELFFile<ELFT>::Elf_Ehdr &Ehdr = HeadersFile->getHeader();
1935 Obj.Is64Bits = Ehdr.e_ident[EI_CLASS] ==ELFCLASS64;
1936 Obj.OSABI = Ehdr.e_ident[EI_OSABI];
1937 Obj.ABIVersion = Ehdr.e_ident[EI_ABIVERSION];
1938 Obj.Type = Ehdr.e_type;
1939 Obj.Machine = Ehdr.e_machine;
1940 Obj.Version = Ehdr.e_version;
1941 Obj.Entry = Ehdr.e_entry;
1942 Obj.Flags = Ehdr.e_flags;
1943
1944if (Error E = readSections(EnsureSymtab))
1945return E;
1946return readProgramHeaders(*HeadersFile);
1947}
1948
1949Writer::~Writer() =default;
1950
1951Reader::~Reader() =default;
1952
1953Expected<std::unique_ptr<Object>>
1954BinaryReader::create(bool/*EnsureSymtab*/) const{
1955returnBinaryELFBuilder(MemBuf, NewSymbolVisibility).build();
1956}
1957
1958Expected<std::vector<IHexRecord>> IHexReader::parse() const{
1959SmallVector<StringRef, 16> Lines;
1960 std::vector<IHexRecord> Records;
1961bool HasSections =false;
1962
1963 MemBuf->getBuffer().split(Lines,'\n');
1964 Records.reserve(Lines.size());
1965for (size_t LineNo = 1; LineNo <= Lines.size(); ++LineNo) {
1966StringRef Line = Lines[LineNo - 1].trim();
1967if (Line.empty())
1968continue;
1969
1970Expected<IHexRecord> R =IHexRecord::parse(Line);
1971if (!R)
1972return parseError(LineNo, R.takeError());
1973if (R->Type ==IHexRecord::EndOfFile)
1974break;
1975 HasSections |= (R->Type ==IHexRecord::Data);
1976 Records.push_back(*R);
1977 }
1978if (!HasSections)
1979return parseError(-1U,"no sections");
1980
1981return std::move(Records);
1982}
1983
1984Expected<std::unique_ptr<Object>>
1985IHexReader::create(bool/*EnsureSymtab*/) const{
1986Expected<std::vector<IHexRecord>> Records =parse();
1987if (!Records)
1988return Records.takeError();
1989
1990returnIHexELFBuilder(*Records).build();
1991}
1992
1993Expected<std::unique_ptr<Object>>ELFReader::create(bool EnsureSymtab) const{
1994auto Obj = std::make_unique<Object>();
1995if (auto *O =dyn_cast<ELFObjectFile<ELF32LE>>(Bin)) {
1996ELFBuilder<ELF32LE> Builder(*O, *Obj, ExtractPartition);
1997if (Error Err = Builder.build(EnsureSymtab))
1998return std::move(Err);
1999return std::move(Obj);
2000 }elseif (auto *O =dyn_cast<ELFObjectFile<ELF64LE>>(Bin)) {
2001ELFBuilder<ELF64LE> Builder(*O, *Obj, ExtractPartition);
2002if (Error Err = Builder.build(EnsureSymtab))
2003return std::move(Err);
2004return std::move(Obj);
2005 }elseif (auto *O =dyn_cast<ELFObjectFile<ELF32BE>>(Bin)) {
2006ELFBuilder<ELF32BE> Builder(*O, *Obj, ExtractPartition);
2007if (Error Err = Builder.build(EnsureSymtab))
2008return std::move(Err);
2009return std::move(Obj);
2010 }elseif (auto *O =dyn_cast<ELFObjectFile<ELF64BE>>(Bin)) {
2011ELFBuilder<ELF64BE> Builder(*O, *Obj, ExtractPartition);
2012if (Error Err = Builder.build(EnsureSymtab))
2013return std::move(Err);
2014return std::move(Obj);
2015 }
2016returncreateStringError(errc::invalid_argument,"invalid file type");
2017}
2018
2019template <class ELFT>voidELFWriter<ELFT>::writeEhdr() {
2020 Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(Buf->getBufferStart());
2021 std::fill(Ehdr.e_ident, Ehdr.e_ident + 16, 0);
2022 Ehdr.e_ident[EI_MAG0] = 0x7f;
2023 Ehdr.e_ident[EI_MAG1] ='E';
2024 Ehdr.e_ident[EI_MAG2] ='L';
2025 Ehdr.e_ident[EI_MAG3] ='F';
2026 Ehdr.e_ident[EI_CLASS] = ELFT::Is64Bits ?ELFCLASS64 :ELFCLASS32;
2027 Ehdr.e_ident[EI_DATA] =
2028 ELFT::Endianness ==llvm::endianness::big ?ELFDATA2MSB :ELFDATA2LSB;
2029 Ehdr.e_ident[EI_VERSION] =EV_CURRENT;
2030 Ehdr.e_ident[EI_OSABI] = Obj.OSABI;
2031 Ehdr.e_ident[EI_ABIVERSION] = Obj.ABIVersion;
2032
2033 Ehdr.e_type = Obj.Type;
2034 Ehdr.e_machine = Obj.Machine;
2035 Ehdr.e_version = Obj.Version;
2036 Ehdr.e_entry = Obj.Entry;
2037// We have to use the fully-qualified name llvm::size
2038// since some compilers complain on ambiguous resolution.
2039 Ehdr.e_phnum =llvm::size(Obj.segments());
2040 Ehdr.e_phoff = (Ehdr.e_phnum != 0) ? Obj.ProgramHdrSegment.Offset : 0;
2041 Ehdr.e_phentsize = (Ehdr.e_phnum != 0) ?sizeof(Elf_Phdr) : 0;
2042 Ehdr.e_flags = Obj.Flags;
2043 Ehdr.e_ehsize =sizeof(Elf_Ehdr);
2044if (WriteSectionHeaders && Obj.sections().size() != 0) {
2045 Ehdr.e_shentsize =sizeof(Elf_Shdr);
2046 Ehdr.e_shoff = Obj.SHOff;
2047// """
2048// If the number of sections is greater than or equal to
2049// SHN_LORESERVE (0xff00), this member has the value zero and the actual
2050// number of section header table entries is contained in the sh_size field
2051// of the section header at index 0.
2052// """
2053auto Shnum = Obj.sections().size() + 1;
2054if (Shnum >=SHN_LORESERVE)
2055 Ehdr.e_shnum = 0;
2056else
2057 Ehdr.e_shnum = Shnum;
2058// """
2059// If the section name string table section index is greater than or equal
2060// to SHN_LORESERVE (0xff00), this member has the value SHN_XINDEX (0xffff)
2061// and the actual index of the section name string table section is
2062// contained in the sh_link field of the section header at index 0.
2063// """
2064if (Obj.SectionNames->Index >=SHN_LORESERVE)
2065 Ehdr.e_shstrndx =SHN_XINDEX;
2066else
2067 Ehdr.e_shstrndx = Obj.SectionNames->Index;
2068 }else {
2069 Ehdr.e_shentsize = 0;
2070 Ehdr.e_shoff = 0;
2071 Ehdr.e_shnum = 0;
2072 Ehdr.e_shstrndx = 0;
2073 }
2074}
2075
2076template <class ELFT>voidELFWriter<ELFT>::writePhdrs() {
2077for (auto &Seg : Obj.segments())
2078 writePhdr(Seg);
2079}
2080
2081template <class ELFT>voidELFWriter<ELFT>::writeShdrs() {
2082// This reference serves to write the dummy section header at the begining
2083// of the file. It is not used for anything else
2084 Elf_Shdr &Shdr =
2085 *reinterpret_cast<Elf_Shdr *>(Buf->getBufferStart() + Obj.SHOff);
2086Shdr.sh_name = 0;
2087Shdr.sh_type =SHT_NULL;
2088Shdr.sh_flags = 0;
2089Shdr.sh_addr = 0;
2090Shdr.sh_offset = 0;
2091// See writeEhdr for why we do this.
2092uint64_t Shnum = Obj.sections().size() + 1;
2093if (Shnum >=SHN_LORESERVE)
2094Shdr.sh_size = Shnum;
2095else
2096Shdr.sh_size = 0;
2097// See writeEhdr for why we do this.
2098if (Obj.SectionNames !=nullptr && Obj.SectionNames->Index >=SHN_LORESERVE)
2099Shdr.sh_link = Obj.SectionNames->Index;
2100else
2101Shdr.sh_link = 0;
2102Shdr.sh_info = 0;
2103Shdr.sh_addralign = 0;
2104Shdr.sh_entsize = 0;
2105
2106for (SectionBase &Sec : Obj.sections())
2107 writeShdr(Sec);
2108}
2109
2110template <class ELFT>ErrorELFWriter<ELFT>::writeSectionData() {
2111for (SectionBase &Sec : Obj.sections())
2112// Segments are responsible for writing their contents, so only write the
2113// section data if the section is not in a segment. Note that this renders
2114// sections in segments effectively immutable.
2115if (Sec.ParentSegment ==nullptr)
2116if (Error Err = Sec.accept(*SecWriter))
2117return Err;
2118
2119returnError::success();
2120}
2121
2122template <class ELFT>voidELFWriter<ELFT>::writeSegmentData() {
2123for (Segment &Seg : Obj.segments()) {
2124size_tSize = std::min<size_t>(Seg.FileSize, Seg.getContents().size());
2125 std::memcpy(Buf->getBufferStart() + Seg.Offset, Seg.getContents().data(),
2126Size);
2127 }
2128
2129for (constauto &it : Obj.getUpdatedSections()) {
2130SectionBase *Sec = it.first;
2131ArrayRef<uint8_t>Data = it.second;
2132
2133auto *Parent = Sec->ParentSegment;
2134assert(Parent &&"This section should've been part of a segment.");
2135uint64_tOffset =
2136 Sec->OriginalOffset - Parent->OriginalOffset + Parent->Offset;
2137llvm::copy(Data, Buf->getBufferStart() +Offset);
2138 }
2139
2140// Iterate over removed sections and overwrite their old data with zeroes.
2141for (auto &Sec : Obj.removedSections()) {
2142Segment *Parent = Sec.ParentSegment;
2143if (Parent ==nullptr || Sec.Type ==SHT_NOBITS || Sec.Size == 0)
2144continue;
2145uint64_tOffset =
2146 Sec.OriginalOffset - Parent->OriginalOffset + Parent->Offset;
2147 std::memset(Buf->getBufferStart() +Offset, 0, Sec.Size);
2148 }
2149}
2150
2151template <class ELFT>
2152ELFWriter<ELFT>::ELFWriter(Object &Obj,raw_ostream &Buf,bool WSH,
2153bool OnlyKeepDebug)
2154 :Writer(Obj, Buf), WriteSectionHeaders(WSH && Obj.HadShdrs),
2155 OnlyKeepDebug(OnlyKeepDebug) {}
2156
2157Error Object::updateSectionData(SecPtr &Sec,ArrayRef<uint8_t>Data) {
2158if (!Sec->hasContents())
2159returncreateStringError(
2160errc::invalid_argument,
2161"section '%s' cannot be updated because it does not have contents",
2162 Sec->Name.c_str());
2163
2164if (Data.size() > Sec->Size && Sec->ParentSegment)
2165returncreateStringError(errc::invalid_argument,
2166"cannot fit data of size %zu into section '%s' "
2167"with size %" PRIu64" that is part of a segment",
2168Data.size(), Sec->Name.c_str(), Sec->Size);
2169
2170if (!Sec->ParentSegment) {
2171 Sec = std::make_unique<OwnedDataSection>(*Sec,Data);
2172 }else {
2173// The segment writer will be in charge of updating these contents.
2174 Sec->Size =Data.size();
2175 UpdatedSections[Sec.get()] =Data;
2176 }
2177
2178returnError::success();
2179}
2180
2181ErrorObject::updateSection(StringRefName,ArrayRef<uint8_t>Data) {
2182auto It =llvm::find_if(Sections,
2183 [&](const SecPtr &Sec) {return Sec->Name ==Name; });
2184if (It == Sections.end())
2185returncreateStringError(errc::invalid_argument,"section '%s' not found",
2186Name.str().c_str());
2187return updateSectionData(*It,Data);
2188}
2189
2190Error Object::updateSectionData(SectionBase &S,ArrayRef<uint8_t>Data) {
2191auto It =llvm::find_if(Sections,
2192 [&](const SecPtr &Sec) {return Sec.get() == &S; });
2193assert(It != Sections.end() &&"The section should belong to the object");
2194return updateSectionData(*It,Data);
2195}
2196
2197ErrorObject::removeSections(
2198bool AllowBrokenLinks, std::function<bool(constSectionBase &)>ToRemove) {
2199
2200auto Iter = std::stable_partition(
2201 std::begin(Sections), std::end(Sections), [=](const SecPtr &Sec) {
2202if (ToRemove(*Sec))
2203returnfalse;
2204// TODO: A compressed relocation section may be recognized as
2205// RelocationSectionBase. We don't want such a section to be removed.
2206if (isa<CompressedSection>(Sec))
2207returntrue;
2208if (auto RelSec = dyn_cast<RelocationSectionBase>(Sec.get())) {
2209 if (auto ToRelSec = RelSec->getSection())
2210 return !ToRemove(*ToRelSec);
2211 }
2212// Remove empty group sections.
2213if (Sec->Type ==ELF::SHT_GROUP) {
2214 auto GroupSec = cast<GroupSection>(Sec.get());
2215 return !llvm::all_of(GroupSec->members(), ToRemove);
2216 }
2217returntrue;
2218 });
2219if (SymbolTable !=nullptr &&ToRemove(*SymbolTable))
2220SymbolTable =nullptr;
2221if (SectionNames !=nullptr &&ToRemove(*SectionNames))
2222SectionNames =nullptr;
2223if (SectionIndexTable !=nullptr &&ToRemove(*SectionIndexTable))
2224SectionIndexTable =nullptr;
2225// Now make sure there are no remaining references to the sections that will
2226// be removed. Sometimes it is impossible to remove a reference so we emit
2227// an error here instead.
2228 std::unordered_set<const SectionBase *> RemoveSections;
2229 RemoveSections.reserve(std::distance(Iter, std::end(Sections)));
2230for (auto &RemoveSec :make_range(Iter, std::end(Sections))) {
2231for (auto &Segment : Segments)
2232Segment->removeSection(RemoveSec.get());
2233 RemoveSec->onRemove();
2234 RemoveSections.insert(RemoveSec.get());
2235 }
2236
2237// For each section that remains alive, we want to remove the dead references.
2238// This either might update the content of the section (e.g. remove symbols
2239// from symbol table that belongs to removed section) or trigger an error if
2240// a live section critically depends on a section being removed somehow
2241// (e.g. the removed section is referenced by a relocation).
2242for (auto &KeepSec :make_range(std::begin(Sections), Iter)) {
2243if (Error E = KeepSec->removeSectionReferences(
2244 AllowBrokenLinks, [&RemoveSections](constSectionBase *Sec) {
2245 return RemoveSections.find(Sec) != RemoveSections.end();
2246 }))
2247return E;
2248 }
2249
2250// Transfer removed sections into the Object RemovedSections container for use
2251// later.
2252 std::move(Iter, Sections.end(), std::back_inserter(RemovedSections));
2253// Now finally get rid of them all together.
2254 Sections.erase(Iter, std::end(Sections));
2255returnError::success();
2256}
2257
2258ErrorObject::replaceSections(
2259constDenseMap<SectionBase *, SectionBase *> &FromTo) {
2260auto SectionIndexLess = [](const SecPtr &Lhs,const SecPtr &Rhs) {
2261return Lhs->Index < Rhs->Index;
2262 };
2263assert(llvm::is_sorted(Sections, SectionIndexLess) &&
2264"Sections are expected to be sorted by Index");
2265// Set indices of new sections so that they can be later sorted into positions
2266// of removed ones.
2267for (auto &I : FromTo)
2268I.second->Index =I.first->Index;
2269
2270// Notify all sections about the replacement.
2271for (auto &Sec : Sections)
2272 Sec->replaceSectionReferences(FromTo);
2273
2274if (Error E =removeSections(
2275/*AllowBrokenLinks=*/false,
2276 [=](constSectionBase &Sec) {return FromTo.count(&Sec) > 0; }))
2277return E;
2278llvm::sort(Sections, SectionIndexLess);
2279returnError::success();
2280}
2281
2282ErrorObject::removeSymbols(function_ref<bool(constSymbol &)>ToRemove) {
2283if (SymbolTable)
2284for (const SecPtr &Sec : Sections)
2285if (Error E = Sec->removeSymbols(ToRemove))
2286return E;
2287returnError::success();
2288}
2289
2290ErrorObject::addNewSymbolTable() {
2291assert(!SymbolTable &&"Object must not has a SymbolTable.");
2292
2293// Reuse an existing SHT_STRTAB section if it exists.
2294StringTableSection *StrTab =nullptr;
2295for (SectionBase &Sec :sections()) {
2296if (Sec.Type ==ELF::SHT_STRTAB && !(Sec.Flags &SHF_ALLOC)) {
2297 StrTab =static_cast<StringTableSection *>(&Sec);
2298
2299// Prefer a string table that is not the section header string table, if
2300// such a table exists.
2301if (SectionNames != &Sec)
2302break;
2303 }
2304 }
2305if (!StrTab)
2306 StrTab = &addSection<StringTableSection>();
2307
2308SymbolTableSection &SymTab = addSection<SymbolTableSection>();
2309 SymTab.Name =".symtab";
2310 SymTab.Link = StrTab->Index;
2311if (Error Err = SymTab.initialize(sections()))
2312return Err;
2313 SymTab.addSymbol("", 0, 0,nullptr, 0, 0, 0, 0);
2314
2315SymbolTable = &SymTab;
2316
2317returnError::success();
2318}
2319
2320// Orders segments such that if x = y->ParentSegment then y comes before x.
2321staticvoidorderSegments(std::vector<Segment *> &Segments) {
2322llvm::stable_sort(Segments,compareSegmentsByOffset);
2323}
2324
2325// This function finds a consistent layout for a list of segments starting from
2326// an Offset. It assumes that Segments have been sorted by orderSegments and
2327// returns an Offset one past the end of the last segment.
2328staticuint64_tlayoutSegments(std::vector<Segment *> &Segments,
2329uint64_tOffset) {
2330assert(llvm::is_sorted(Segments,compareSegmentsByOffset));
2331// The only way a segment should move is if a section was between two
2332// segments and that section was removed. If that section isn't in a segment
2333// then it's acceptable, but not ideal, to simply move it to after the
2334// segments. So we can simply layout segments one after the other accounting
2335// for alignment.
2336for (Segment *Seg : Segments) {
2337// We assume that segments have been ordered by OriginalOffset and Index
2338// such that a parent segment will always come before a child segment in
2339// OrderedSegments. This means that the Offset of the ParentSegment should
2340// already be set and we can set our offset relative to it.
2341if (Seg->ParentSegment !=nullptr) {
2342Segment *Parent = Seg->ParentSegment;
2343 Seg->Offset =
2344 Parent->Offset + Seg->OriginalOffset - Parent->OriginalOffset;
2345 }else {
2346 Seg->Offset =
2347alignTo(Offset, std::max<uint64_t>(Seg->Align, 1), Seg->VAddr);
2348 }
2349Offset = std::max(Offset, Seg->Offset + Seg->FileSize);
2350 }
2351returnOffset;
2352}
2353
2354// This function finds a consistent layout for a list of sections. It assumes
2355// that the ->ParentSegment of each section has already been laid out. The
2356// supplied starting Offset is used for the starting offset of any section that
2357// does not have a ParentSegment. It returns either the offset given if all
2358// sections had a ParentSegment or an offset one past the last section if there
2359// was a section that didn't have a ParentSegment.
2360template <class Range>
2361staticuint64_tlayoutSections(Range Sections,uint64_tOffset) {
2362// Now the offset of every segment has been set we can assign the offsets
2363// of each section. For sections that are covered by a segment we should use
2364// the segment's original offset and the section's original offset to compute
2365// the offset from the start of the segment. Using the offset from the start
2366// of the segment we can assign a new offset to the section. For sections not
2367// covered by segments we can just bump Offset to the next valid location.
2368// While it is not necessary, layout the sections in the order based on their
2369// original offsets to resemble the input file as close as possible.
2370 std::vector<SectionBase *> OutOfSegmentSections;
2371uint32_t Index = 1;
2372for (auto &Sec : Sections) {
2373 Sec.Index = Index++;
2374if (Sec.ParentSegment !=nullptr) {
2375constSegment &Segment = *Sec.ParentSegment;
2376 Sec.Offset =
2377Segment.Offset + (Sec.OriginalOffset -Segment.OriginalOffset);
2378 }else
2379 OutOfSegmentSections.push_back(&Sec);
2380 }
2381
2382llvm::stable_sort(OutOfSegmentSections,
2383 [](constSectionBase *Lhs,constSectionBase *Rhs) {
2384return Lhs->OriginalOffset < Rhs->OriginalOffset;
2385 });
2386for (auto *Sec : OutOfSegmentSections) {
2387Offset =alignTo(Offset, Sec->Align == 0 ? 1 : Sec->Align);
2388 Sec->Offset =Offset;
2389if (Sec->Type !=SHT_NOBITS)
2390Offset += Sec->Size;
2391 }
2392returnOffset;
2393}
2394
2395// Rewrite sh_offset after some sections are changed to SHT_NOBITS and thus
2396// occupy no space in the file.
2397staticuint64_tlayoutSectionsForOnlyKeepDebug(Object &Obj,uint64_t Off) {
2398// The layout algorithm requires the sections to be handled in the order of
2399// their offsets in the input file, at least inside segments.
2400 std::vector<SectionBase *> Sections;
2401 Sections.reserve(Obj.sections().size());
2402uint32_t Index = 1;
2403for (auto &Sec : Obj.sections()) {
2404 Sec.Index = Index++;
2405 Sections.push_back(&Sec);
2406 }
2407llvm::stable_sort(Sections,
2408 [](constSectionBase *Lhs,constSectionBase *Rhs) {
2409return Lhs->OriginalOffset < Rhs->OriginalOffset;
2410 });
2411
2412for (auto *Sec : Sections) {
2413auto *FirstSec = Sec->ParentSegment && Sec->ParentSegment->Type ==PT_LOAD
2414 ? Sec->ParentSegment->firstSection()
2415 :nullptr;
2416
2417// The first section in a PT_LOAD has to have congruent offset and address
2418// modulo the alignment, which usually equals the maximum page size.
2419if (FirstSec && FirstSec == Sec)
2420 Off =alignTo(Off, Sec->ParentSegment->Align, Sec->Addr);
2421
2422// sh_offset is not significant for SHT_NOBITS sections, but the congruence
2423// rule must be followed if it is the first section in a PT_LOAD. Do not
2424// advance Off.
2425if (Sec->Type ==SHT_NOBITS) {
2426 Sec->Offset = Off;
2427continue;
2428 }
2429
2430if (!FirstSec) {
2431// FirstSec being nullptr generally means that Sec does not have the
2432// SHF_ALLOC flag.
2433 Off = Sec->Align ?alignTo(Off, Sec->Align) : Off;
2434 }elseif (FirstSec != Sec) {
2435// The offset is relative to the first section in the PT_LOAD segment. Use
2436// sh_offset for non-SHF_ALLOC sections.
2437 Off = Sec->OriginalOffset - FirstSec->OriginalOffset + FirstSec->Offset;
2438 }
2439 Sec->Offset = Off;
2440 Off += Sec->Size;
2441 }
2442return Off;
2443}
2444
2445// Rewrite p_offset and p_filesz of non-PT_PHDR segments after sh_offset values
2446// have been updated.
2447staticuint64_tlayoutSegmentsForOnlyKeepDebug(std::vector<Segment *> &Segments,
2448uint64_t HdrEnd) {
2449uint64_t MaxOffset = 0;
2450for (Segment *Seg : Segments) {
2451if (Seg->Type ==PT_PHDR)
2452continue;
2453
2454// The segment offset is generally the offset of the first section.
2455//
2456// For a segment containing no section (see sectionWithinSegment), if it has
2457// a parent segment, copy the parent segment's offset field. This works for
2458// empty PT_TLS. If no parent segment, use 0: the segment is not useful for
2459// debugging anyway.
2460constSectionBase *FirstSec = Seg->firstSection();
2461uint64_tOffset =
2462 FirstSec ? FirstSec->Offset
2463 : (Seg->ParentSegment ? Seg->ParentSegment->Offset : 0);
2464uint64_t FileSize = 0;
2465for (constSectionBase *Sec : Seg->Sections) {
2466uint64_tSize = Sec->Type ==SHT_NOBITS ? 0 : Sec->Size;
2467if (Sec->Offset +Size >Offset)
2468 FileSize = std::max(FileSize, Sec->Offset +Size -Offset);
2469 }
2470
2471// If the segment includes EHDR and program headers, don't make it smaller
2472// than the headers.
2473if (Seg->Offset < HdrEnd && HdrEnd <= Seg->Offset + Seg->FileSize) {
2474 FileSize +=Offset - Seg->Offset;
2475Offset = Seg->Offset;
2476 FileSize = std::max(FileSize, HdrEnd -Offset);
2477 }
2478
2479 Seg->Offset =Offset;
2480 Seg->FileSize = FileSize;
2481 MaxOffset = std::max(MaxOffset,Offset + FileSize);
2482 }
2483return MaxOffset;
2484}
2485
2486template <class ELFT>voidELFWriter<ELFT>::initEhdrSegment() {
2487Segment &ElfHdr = Obj.ElfHdrSegment;
2488 ElfHdr.Type =PT_PHDR;
2489 ElfHdr.Flags = 0;
2490 ElfHdr.VAddr = 0;
2491 ElfHdr.PAddr = 0;
2492 ElfHdr.FileSize = ElfHdr.MemSize =sizeof(Elf_Ehdr);
2493 ElfHdr.Align = 0;
2494}
2495
2496template <class ELFT>voidELFWriter<ELFT>::assignOffsets() {
2497// We need a temporary list of segments that has a special order to it
2498// so that we know that anytime ->ParentSegment is set that segment has
2499// already had its offset properly set.
2500 std::vector<Segment *> OrderedSegments;
2501for (Segment &Segment : Obj.segments())
2502 OrderedSegments.push_back(&Segment);
2503 OrderedSegments.push_back(&Obj.ElfHdrSegment);
2504 OrderedSegments.push_back(&Obj.ProgramHdrSegment);
2505orderSegments(OrderedSegments);
2506
2507uint64_tOffset;
2508if (OnlyKeepDebug) {
2509// For --only-keep-debug, the sections that did not preserve contents were
2510// changed to SHT_NOBITS. We now rewrite sh_offset fields of sections, and
2511// then rewrite p_offset/p_filesz of program headers.
2512uint64_t HdrEnd =
2513sizeof(Elf_Ehdr) +llvm::size(Obj.segments()) *sizeof(Elf_Phdr);
2514Offset =layoutSectionsForOnlyKeepDebug(Obj, HdrEnd);
2515Offset = std::max(Offset,
2516layoutSegmentsForOnlyKeepDebug(OrderedSegments, HdrEnd));
2517 }else {
2518// Offset is used as the start offset of the first segment to be laid out.
2519// Since the ELF Header (ElfHdrSegment) must be at the start of the file,
2520// we start at offset 0.
2521Offset =layoutSegments(OrderedSegments, 0);
2522Offset =layoutSections(Obj.sections(),Offset);
2523 }
2524// If we need to write the section header table out then we need to align the
2525// Offset so that SHOffset is valid.
2526if (WriteSectionHeaders)
2527Offset =alignTo(Offset,sizeof(Elf_Addr));
2528 Obj.SHOff =Offset;
2529}
2530
2531template <class ELFT>size_tELFWriter<ELFT>::totalSize() const{
2532// We already have the section header offset so we can calculate the total
2533// size by just adding up the size of each section header.
2534if (!WriteSectionHeaders)
2535return Obj.SHOff;
2536size_t ShdrCount = Obj.sections().size() + 1;// Includes null shdr.
2537return Obj.SHOff + ShdrCount *sizeof(Elf_Shdr);
2538}
2539
2540template <class ELFT>ErrorELFWriter<ELFT>::write() {
2541// Segment data must be written first, so that the ELF header and program
2542// header tables can overwrite it, if covered by a segment.
2543 writeSegmentData();
2544 writeEhdr();
2545 writePhdrs();
2546if (Error E = writeSectionData())
2547return E;
2548if (WriteSectionHeaders)
2549 writeShdrs();
2550
2551// TODO: Implement direct writing to the output stream (without intermediate
2552// memory buffer Buf).
2553 Out.write(Buf->getBufferStart(), Buf->getBufferSize());
2554returnError::success();
2555}
2556
2557staticErrorremoveUnneededSections(Object &Obj) {
2558// We can remove an empty symbol table from non-relocatable objects.
2559// Relocatable objects typically have relocation sections whose
2560// sh_link field points to .symtab, so we can't remove .symtab
2561// even if it is empty.
2562if (Obj.isRelocatable() || Obj.SymbolTable ==nullptr ||
2563 !Obj.SymbolTable->empty())
2564returnError::success();
2565
2566// .strtab can be used for section names. In such a case we shouldn't
2567// remove it.
2568auto *StrTab = Obj.SymbolTable->getStrTab() == Obj.SectionNames
2569 ? nullptr
2570 : Obj.SymbolTable->getStrTab();
2571return Obj.removeSections(false, [&](constSectionBase &Sec) {
2572return &Sec == Obj.SymbolTable || &Sec == StrTab;
2573 });
2574}
2575
2576template <class ELFT>ErrorELFWriter<ELFT>::finalize() {
2577// It could happen that SectionNames has been removed and yet the user wants
2578// a section header table output. We need to throw an error if a user tries
2579// to do that.
2580if (Obj.SectionNames ==nullptr && WriteSectionHeaders)
2581returncreateStringError(llvm::errc::invalid_argument,
2582"cannot write section header table because "
2583"section header string table was removed");
2584
2585if (Error E =removeUnneededSections(Obj))
2586return E;
2587
2588// If the .symtab indices have not been changed, restore the sh_link to
2589// .symtab for sections that were linked to .symtab.
2590if (Obj.SymbolTable && !Obj.SymbolTable->indicesChanged())
2591for (SectionBase &Sec : Obj.sections())
2592 Sec.restoreSymTabLink(*Obj.SymbolTable);
2593
2594// We need to assign indexes before we perform layout because we need to know
2595// if we need large indexes or not. We can assign indexes first and check as
2596// we go to see if we will actully need large indexes.
2597bool NeedsLargeIndexes =false;
2598if (Obj.sections().size() >=SHN_LORESERVE) {
2599SectionTableRef Sections = Obj.sections();
2600// Sections doesn't include the null section header, so account for this
2601// when skipping the first N sections.
2602 NeedsLargeIndexes =
2603any_of(drop_begin(Sections,SHN_LORESERVE - 1),
2604 [](constSectionBase &Sec) {return Sec.HasSymbol; });
2605// TODO: handle case where only one section needs the large index table but
2606// only needs it because the large index table hasn't been removed yet.
2607 }
2608
2609if (NeedsLargeIndexes) {
2610// This means we definitely need to have a section index table but if we
2611// already have one then we should use it instead of making a new one.
2612if (Obj.SymbolTable !=nullptr && Obj.SectionIndexTable ==nullptr) {
2613// Addition of a section to the end does not invalidate the indexes of
2614// other sections and assigns the correct index to the new section.
2615auto &Shndx = Obj.addSection<SectionIndexSection>();
2616 Obj.SymbolTable->setShndxTable(&Shndx);
2617 Shndx.setSymTab(Obj.SymbolTable);
2618 }
2619 }else {
2620// Since we don't need SectionIndexTable we should remove it and all
2621// references to it.
2622if (Obj.SectionIndexTable !=nullptr) {
2623// We do not support sections referring to the section index table.
2624if (Error E = Obj.removeSections(false/*AllowBrokenLinks*/,
2625 [this](constSectionBase &Sec) {
2626 return &Sec == Obj.SectionIndexTable;
2627 }))
2628return E;
2629 }
2630 }
2631
2632// Make sure we add the names of all the sections. Importantly this must be
2633// done after we decide to add or remove SectionIndexes.
2634if (Obj.SectionNames !=nullptr)
2635for (constSectionBase &Sec : Obj.sections())
2636 Obj.SectionNames->addString(Sec.Name);
2637
2638 initEhdrSegment();
2639
2640// Before we can prepare for layout the indexes need to be finalized.
2641// Also, the output arch may not be the same as the input arch, so fix up
2642// size-related fields before doing layout calculations.
2643uint64_t Index = 0;
2644auto SecSizer = std::make_unique<ELFSectionSizer<ELFT>>();
2645for (SectionBase &Sec : Obj.sections()) {
2646 Sec.Index = Index++;
2647if (Error Err = Sec.accept(*SecSizer))
2648return Err;
2649 }
2650
2651// The symbol table does not update all other sections on update. For
2652// instance, symbol names are not added as new symbols are added. This means
2653// that some sections, like .strtab, don't yet have their final size.
2654if (Obj.SymbolTable !=nullptr)
2655 Obj.SymbolTable->prepareForLayout();
2656
2657// Now that all strings are added we want to finalize string table builders,
2658// because that affects section sizes which in turn affects section offsets.
2659for (SectionBase &Sec : Obj.sections())
2660if (auto StrTab = dyn_cast<StringTableSection>(&Sec))
2661 StrTab->prepareForLayout();
2662
2663 assignOffsets();
2664
2665// layoutSections could have modified section indexes, so we need
2666// to fill the index table after assignOffsets.
2667if (Obj.SymbolTable !=nullptr)
2668 Obj.SymbolTable->fillShndxTable();
2669
2670// Finally now that all offsets and indexes have been set we can finalize any
2671// remaining issues.
2672uint64_tOffset = Obj.SHOff +sizeof(Elf_Shdr);
2673for (SectionBase &Sec : Obj.sections()) {
2674 Sec.HeaderOffset =Offset;
2675Offset +=sizeof(Elf_Shdr);
2676if (WriteSectionHeaders)
2677 Sec.NameIndex = Obj.SectionNames->findIndex(Sec.Name);
2678 Sec.finalize();
2679 }
2680
2681size_t TotalSize = totalSize();
2682 Buf =WritableMemoryBuffer::getNewMemBuffer(TotalSize);
2683if (!Buf)
2684returncreateStringError(errc::not_enough_memory,
2685"failed to allocate memory buffer of " +
2686Twine::utohexstr(TotalSize) +" bytes");
2687
2688 SecWriter = std::make_unique<ELFSectionWriter<ELFT>>(*Buf);
2689returnError::success();
2690}
2691
2692ErrorBinaryWriter::write() {
2693SmallVector<const SectionBase *, 30> SectionsToWrite;
2694for (constSectionBase &Sec :Obj.allocSections()) {
2695if (Sec.Type !=SHT_NOBITS && Sec.Size > 0)
2696 SectionsToWrite.push_back(&Sec);
2697 }
2698
2699if (SectionsToWrite.empty())
2700returnError::success();
2701
2702llvm::stable_sort(SectionsToWrite,
2703 [](constSectionBase *LHS,constSectionBase *RHS) {
2704returnLHS->Offset <RHS->Offset;
2705 });
2706
2707assert(SectionsToWrite.front()->Offset == 0);
2708
2709for (size_t i = 0; i != SectionsToWrite.size(); ++i) {
2710constSectionBase &Sec = *SectionsToWrite[i];
2711if (Error Err = Sec.accept(*SecWriter))
2712return Err;
2713if (GapFill == 0)
2714continue;
2715uint64_t PadOffset = (i < SectionsToWrite.size() - 1)
2716 ? SectionsToWrite[i + 1]->Offset
2717 :Buf->getBufferSize();
2718assert(PadOffset <= Buf->getBufferSize());
2719assert(Sec.Offset + Sec.Size <= PadOffset);
2720 std::fill(Buf->getBufferStart() + Sec.Offset + Sec.Size,
2721Buf->getBufferStart() + PadOffset, GapFill);
2722 }
2723
2724// TODO: Implement direct writing to the output stream (without intermediate
2725// memory buffer Buf).
2726Out.write(Buf->getBufferStart(),Buf->getBufferSize());
2727returnError::success();
2728}
2729
2730ErrorBinaryWriter::finalize() {
2731// Compute the section LMA based on its sh_offset and the containing segment's
2732// p_offset and p_paddr. Also compute the minimum LMA of all non-empty
2733// sections as MinAddr. In the output, the contents between address 0 and
2734// MinAddr will be skipped.
2735uint64_t MinAddr =UINT64_MAX;
2736for (SectionBase &Sec :Obj.allocSections()) {
2737if (Sec.ParentSegment !=nullptr)
2738 Sec.Addr =
2739 Sec.Offset - Sec.ParentSegment->Offset + Sec.ParentSegment->PAddr;
2740if (Sec.Type !=SHT_NOBITS && Sec.Size > 0)
2741 MinAddr = std::min(MinAddr, Sec.Addr);
2742 }
2743
2744// Now that every section has been laid out we just need to compute the total
2745// file size. This might not be the same as the offset returned by
2746// layoutSections, because we want to truncate the last segment to the end of
2747// its last non-empty section, to match GNU objcopy's behaviour.
2748 TotalSize = PadTo > MinAddr ? PadTo - MinAddr : 0;
2749for (SectionBase &Sec :Obj.allocSections())
2750if (Sec.Type !=SHT_NOBITS && Sec.Size > 0) {
2751 Sec.Offset = Sec.Addr - MinAddr;
2752 TotalSize = std::max(TotalSize, Sec.Offset + Sec.Size);
2753 }
2754
2755Buf =WritableMemoryBuffer::getNewMemBuffer(TotalSize);
2756if (!Buf)
2757returncreateStringError(errc::not_enough_memory,
2758"failed to allocate memory buffer of " +
2759Twine::utohexstr(TotalSize) +" bytes");
2760 SecWriter = std::make_unique<BinarySectionWriter>(*Buf);
2761returnError::success();
2762}
2763
2764ErrorASCIIHexWriter::checkSection(constSectionBase &S) const{
2765if (addressOverflows32bit(S.Addr) ||
2766addressOverflows32bit(S.Addr + S.Size - 1))
2767returncreateStringError(
2768errc::invalid_argument,
2769"section '%s' address range [0x%llx, 0x%llx] is not 32 bit",
2770 S.Name.c_str(), S.Addr, S.Addr + S.Size - 1);
2771returnError::success();
2772}
2773
2774ErrorASCIIHexWriter::finalize() {
2775// We can't write 64-bit addresses.
2776if (addressOverflows32bit(Obj.Entry))
2777returncreateStringError(errc::invalid_argument,
2778"entry point address 0x%llx overflows 32 bits",
2779Obj.Entry);
2780
2781for (constSectionBase &S :Obj.sections()) {
2782if ((S.Flags &ELF::SHF_ALLOC) && S.Type !=ELF::SHT_NOBITS && S.Size > 0) {
2783if (Error E =checkSection(S))
2784return E;
2785Sections.push_back(&S);
2786 }
2787 }
2788
2789llvm::sort(Sections, [](constSectionBase *A,constSectionBase *B) {
2790returnsectionPhysicalAddr(A) <sectionPhysicalAddr(B);
2791 });
2792
2793 std::unique_ptr<WritableMemoryBuffer> EmptyBuffer =
2794WritableMemoryBuffer::getNewMemBuffer(0);
2795if (!EmptyBuffer)
2796returncreateStringError(errc::not_enough_memory,
2797"failed to allocate memory buffer of 0 bytes");
2798
2799Expected<size_t> ExpTotalSize =getTotalSize(*EmptyBuffer);
2800if (!ExpTotalSize)
2801return ExpTotalSize.takeError();
2802TotalSize = *ExpTotalSize;
2803
2804Buf =WritableMemoryBuffer::getNewMemBuffer(TotalSize);
2805if (!Buf)
2806returncreateStringError(errc::not_enough_memory,
2807"failed to allocate memory buffer of 0x" +
2808Twine::utohexstr(TotalSize) +" bytes");
2809returnError::success();
2810}
2811
2812uint64_t IHexWriter::writeEntryPointRecord(uint8_t *Buf) {
2813IHexLineData HexData;
2814uint8_tData[4] = {};
2815// We don't write entry point record if entry is zero.
2816if (Obj.Entry == 0)
2817return 0;
2818
2819if (Obj.Entry <= 0xFFFFFU) {
2820Data[0] = ((Obj.Entry & 0xF0000U) >> 12) & 0xFF;
2821support::endian::write(&Data[2],static_cast<uint16_t>(Obj.Entry),
2822llvm::endianness::big);
2823 HexData =IHexRecord::getLine(IHexRecord::StartAddr80x86, 0,Data);
2824 }else {
2825support::endian::write(Data,static_cast<uint32_t>(Obj.Entry),
2826llvm::endianness::big);
2827 HexData =IHexRecord::getLine(IHexRecord::StartAddr, 0,Data);
2828 }
2829 memcpy(Buf, HexData.data(), HexData.size());
2830return HexData.size();
2831}
2832
2833uint64_t IHexWriter::writeEndOfFileRecord(uint8_t *Buf) {
2834IHexLineData HexData =IHexRecord::getLine(IHexRecord::EndOfFile, 0, {});
2835 memcpy(Buf, HexData.data(), HexData.size());
2836return HexData.size();
2837}
2838
2839Expected<size_t>
2840IHexWriter::getTotalSize(WritableMemoryBuffer &EmptyBuffer) const{
2841IHexSectionWriterBase LengthCalc(EmptyBuffer);
2842for (constSectionBase *Sec :Sections)
2843if (Error Err = Sec->accept(LengthCalc))
2844return std::move(Err);
2845
2846// We need space to write section records + StartAddress record
2847// (if start adress is not zero) + EndOfFile record.
2848return LengthCalc.getBufferOffset() +
2849 (Obj.Entry ?IHexRecord::getLineLength(4) : 0) +
2850IHexRecord::getLineLength(0);
2851}
2852
2853ErrorIHexWriter::write() {
2854IHexSectionWriterWriter(*Buf);
2855// Write sections.
2856for (constSectionBase *Sec :Sections)
2857if (Error Err = Sec->accept(Writer))
2858return Err;
2859
2860uint64_tOffset =Writer.getBufferOffset();
2861// Write entry point address.
2862Offset += writeEntryPointRecord(
2863reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +Offset);
2864// Write EOF.
2865Offset += writeEndOfFileRecord(
2866reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +Offset);
2867assert(Offset ==TotalSize);
2868
2869// TODO: Implement direct writing to the output stream (without intermediate
2870// memory buffer Buf).
2871Out.write(Buf->getBufferStart(),Buf->getBufferSize());
2872returnError::success();
2873}
2874
2875ErrorSRECSectionWriterBase::visit(constStringTableSection &Sec) {
2876// Check that the sizer has already done its work.
2877assert(Sec.Size == Sec.StrTabBuilder.getSize() &&
2878"Expected section size to have been finalized");
2879// We don't need to write anything here because the real writer has already
2880// done it.
2881returnError::success();
2882}
2883
2884ErrorSRECSectionWriterBase::visit(constSection &Sec) {
2885writeSection(Sec, Sec.Contents);
2886returnError::success();
2887}
2888
2889ErrorSRECSectionWriterBase::visit(constOwnedDataSection &Sec) {
2890writeSection(Sec, Sec.Data);
2891returnError::success();
2892}
2893
2894ErrorSRECSectionWriterBase::visit(constDynamicRelocationSection &Sec) {
2895writeSection(Sec, Sec.Contents);
2896returnError::success();
2897}
2898
2899voidSRECSectionWriter::writeRecord(SRecord &Record,uint64_t Off) {
2900SRecLineDataData =Record.toString();
2901 memcpy(Out.getBufferStart() + Off,Data.data(),Data.size());
2902}
2903
2904voidSRECSectionWriterBase::writeRecords(uint32_t Entry) {
2905// The ELF header could contain an entry point outside of the sections we have
2906// seen that does not fit the current record Type.
2907Type = std::max(Type,SRecord::getType(Entry));
2908uint64_t Off =HeaderSize;
2909for (SRecord &Record :Records) {
2910Record.Type =Type;
2911writeRecord(Record, Off);
2912 Off +=Record.getSize();
2913 }
2914Offset = Off;
2915}
2916
2917voidSRECSectionWriterBase::writeSection(constSectionBase &S,
2918ArrayRef<uint8_t>Data) {
2919constuint32_t ChunkSize = 16;
2920uint32_tAddress =sectionPhysicalAddr(&S);
2921uint32_t EndAddr =Address + S.Size - 1;
2922Type = std::max(SRecord::getType(EndAddr),Type);
2923while (!Data.empty()) {
2924uint64_t DataSize = std::min<uint64_t>(Data.size(), ChunkSize);
2925SRecordRecord{Type,Address,Data.take_front(DataSize)};
2926Records.push_back(Record);
2927Data =Data.drop_front(DataSize);
2928Address += DataSize;
2929 }
2930}
2931
2932ErrorSRECSectionWriter::visit(constStringTableSection &Sec) {
2933assert(Sec.Size == Sec.StrTabBuilder.getSize() &&
2934"Section size does not match the section's string table builder size");
2935 std::vector<uint8_t>Data(Sec.Size);
2936 Sec.StrTabBuilder.write(Data.data());
2937writeSection(Sec,Data);
2938returnError::success();
2939}
2940
2941SRecLineDataSRecord::toString() const{
2942SRecLineData Line(getSize());
2943auto *Iter = Line.begin();
2944 *Iter++ ='S';
2945 *Iter++ ='0' +Type;
2946// Write 1 byte (2 hex characters) record count.
2947 Iter =toHexStr(getCount(), Iter, 2);
2948// Write the address field with length depending on record type.
2949 Iter =toHexStr(Address, Iter,getAddressSize());
2950// Write data byte by byte.
2951for (uint8_tX :Data)
2952 Iter =toHexStr(X, Iter, 2);
2953// Write the 1 byte checksum.
2954 Iter =toHexStr(getChecksum(), Iter, 2);
2955 *Iter++ ='\r';
2956 *Iter++ ='\n';
2957assert(Iter == Line.end());
2958return Line;
2959}
2960
2961uint8_tSRecord::getChecksum() const{
2962uint32_t Sum =getCount();
2963 Sum += (Address >> 24) & 0xFF;
2964 Sum += (Address >> 16) & 0xFF;
2965 Sum += (Address >> 8) & 0xFF;
2966 Sum +=Address & 0xFF;
2967for (uint8_t Byte :Data)
2968 Sum += Byte;
2969return 0xFF - (Sum & 0xFF);
2970}
2971
2972size_tSRecord::getSize() const{
2973// Type, Count, Checksum, and CRLF are two characters each.
2974return 2 + 2 +getAddressSize() +Data.size() * 2 + 2 + 2;
2975}
2976
2977uint8_tSRecord::getAddressSize() const{
2978switch (Type) {
2979caseType::S2:
2980return 6;
2981caseType::S3:
2982return 8;
2983caseType::S7:
2984return 8;
2985caseType::S8:
2986return 6;
2987default:
2988return 4;
2989 }
2990}
2991
2992uint8_tSRecord::getCount() const{
2993uint8_t DataSize =Data.size();
2994uint8_t ChecksumSize = 1;
2995returngetAddressSize() / 2 + DataSize + ChecksumSize;
2996}
2997
2998uint8_tSRecord::getType(uint32_tAddress) {
2999if (isUInt<16>(Address))
3000returnSRecord::S1;
3001if (isUInt<24>(Address))
3002returnSRecord::S2;
3003returnSRecord::S3;
3004}
3005
3006SRecordSRecord::getHeader(StringRef FileName) {
3007// Header is a record with Type S0, Address 0, and Data that is a
3008// vendor-specific text comment. For the comment we will use the output file
3009// name truncated to 40 characters to match the behavior of GNU objcopy.
3010StringRef HeaderContents = FileName.slice(0, 40);
3011ArrayRef<uint8_t>Data(
3012reinterpret_cast<constuint8_t *>(HeaderContents.data()),
3013 HeaderContents.size());
3014return {SRecord::S0, 0,Data};
3015}
3016
3017size_t SRECWriter::writeHeader(uint8_t *Buf) {
3018SRecLineDataRecord =SRecord::getHeader(OutputFileName).toString();
3019 memcpy(Buf,Record.data(),Record.size());
3020returnRecord.size();
3021}
3022
3023size_t SRECWriter::writeTerminator(uint8_t *Buf,uint8_tType) {
3024assert(Type >=SRecord::S7 &&Type <=SRecord::S9 &&
3025"Invalid record type for terminator");
3026uint32_t Entry =Obj.Entry;
3027SRecLineDataData =SRecord{Type, Entry, {}}.toString();
3028 memcpy(Buf,Data.data(),Data.size());
3029returnData.size();
3030}
3031
3032Expected<size_t>
3033SRECWriter::getTotalSize(WritableMemoryBuffer &EmptyBuffer) const{
3034SRECSizeCalculator SizeCalc(EmptyBuffer, 0);
3035for (constSectionBase *Sec :Sections)
3036if (Error Err = Sec->accept(SizeCalc))
3037return std::move(Err);
3038
3039 SizeCalc.writeRecords(Obj.Entry);
3040// We need to add the size of the Header and Terminator records.
3041SRecord Header =SRecord::getHeader(OutputFileName);
3042uint8_t TerminatorType = 10 - SizeCalc.getType();
3043SRecordTerminator = {TerminatorType,static_cast<uint32_t>(Obj.Entry), {}};
3044return Header.getSize() + SizeCalc.getBufferOffset() +Terminator.getSize();
3045}
3046
3047ErrorSRECWriter::write() {
3048uint32_t HeaderSize =
3049 writeHeader(reinterpret_cast<uint8_t *>(Buf->getBufferStart()));
3050SRECSectionWriterWriter(*Buf, HeaderSize);
3051for (constSectionBase *S :Sections) {
3052if (Error E = S->accept(Writer))
3053return E;
3054 }
3055Writer.writeRecords(Obj.Entry);
3056uint64_tOffset =Writer.getBufferOffset();
3057
3058// An S1 record terminates with an S9 record, S2 with S8, and S3 with S7.
3059uint8_t TerminatorType = 10 -Writer.getType();
3060Offset += writeTerminator(
3061reinterpret_cast<uint8_t *>(Buf->getBufferStart() +Offset),
3062 TerminatorType);
3063assert(Offset ==TotalSize);
3064Out.write(Buf->getBufferStart(),Buf->getBufferSize());
3065returnError::success();
3066}
3067
3068namespacellvm {
3069namespaceobjcopy {
3070namespaceelf {
3071
3072templateclassELFBuilder<ELF64LE>;
3073templateclassELFBuilder<ELF64BE>;
3074templateclassELFBuilder<ELF32LE>;
3075templateclassELFBuilder<ELF32BE>;
3076
3077templateclassELFWriter<ELF64LE>;
3078templateclassELFWriter<ELF64BE>;
3079templateclassELFWriter<ELF32LE>;
3080templateclassELFWriter<ELF32BE>;
3081
3082}// end namespace elf
3083}// end namespace objcopy
3084}// end namespace llvm
Fail
#define Fail
Definition:AArch64Disassembler.cpp:221
ToRemove
ReachingDefAnalysis InstSet & ToRemove
Definition:ARMLowOverheadLoops.cpp:531
ArrayRef.h
ELF.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Machine
COFF::MachineTypes Machine
Definition:COFFYAML.cpp:390
Info
Analysis containing CSE Info
Definition:CSEInfo.cpp:27
Compression.h
Content
T Content
Definition:ELFObjHandler.cpp:89
Shdr
Elf_Shdr Shdr
Definition:ELFObjHandler.cpp:78
Addr
uint64_t Addr
Definition:ELFObjHandler.cpp:79
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
segmentOverlapsSegment
static bool segmentOverlapsSegment(const Segment &Child, const Segment &Parent)
Definition:ELFObject.cpp:1246
setAddend
static void setAddend(Elf_Rel_Impl< ELFT, false > &, uint64_t)
Definition:ELFObject.cpp:965
checkChars
static Error checkChars(StringRef Line)
Definition:ELFObject.cpp:301
orderSegments
static void orderSegments(std::vector< Segment * > &Segments)
Definition:ELFObject.cpp:2321
layoutSegments
static uint64_t layoutSegments(std::vector< Segment * > &Segments, uint64_t Offset)
Definition:ELFObject.cpp:2328
compareSegmentsByOffset
static bool compareSegmentsByOffset(const Segment *A, const Segment *B)
Definition:ELFObject.cpp:1253
layoutSections
static uint64_t layoutSections(Range Sections, uint64_t Offset)
Definition:ELFObject.cpp:2361
layoutSectionsForOnlyKeepDebug
static uint64_t layoutSectionsForOnlyKeepDebug(Object &Obj, uint64_t Off)
Definition:ELFObject.cpp:2397
isValidReservedSectionIndex
static bool isValidReservedSectionIndex(uint16_t Index, uint16_t Machine)
Definition:ELFObject.cpp:648
layoutSegmentsForOnlyKeepDebug
static uint64_t layoutSegmentsForOnlyKeepDebug(std::vector< Segment * > &Segments, uint64_t HdrEnd)
Definition:ELFObject.cpp:2447
getAddend
static void getAddend(uint64_t &, const Elf_Rel_Impl< ELFT, false > &)
Definition:ELFObject.cpp:1647
writeRel
static void writeRel(const RelRange &Relocations, T *Buf, bool IsMips64EL)
Definition:ELFObject.cpp:973
addressOverflows32bit
static bool addressOverflows32bit(uint64_t Addr)
Definition:ELFObject.cpp:193
checkedGetHex
static T checkedGetHex(StringRef S)
Definition:ELFObject.cpp:198
sectionPhysicalAddr
static uint64_t sectionPhysicalAddr(const SectionBase *Sec)
Definition:ELFObject.cpp:343
toHexStr
static Iterator toHexStr(T X, Iterator It, size_t Len)
Definition:ELFObject.cpp:209
checkRecord
static Error checkRecord(const IHexRecord &R)
Definition:ELFObject.cpp:251
initRelocations
static Error initRelocations(RelocationSection *Relocs, T RelRange)
Definition:ELFObject.cpp:1655
removeUnneededSections
static Error removeUnneededSections(Object &Obj)
Definition:ELFObject.cpp:2557
sectionWithinSegment
static bool sectionWithinSegment(const SectionBase &Sec, const Segment &Seg)
Definition:ELFObject.cpp:1216
ELFObject.h
End
bool End
Definition:ELF_riscv.cpp:480
Sym
Symbol * Sym
Definition:ELF_riscv.cpp:479
Endian.h
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
MCELFExtras.h
MCTargetOptions.h
I
#define I(x, y, z)
Definition:MD5.cpp:58
Range
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
if
if(PassOpts->AAPipeline)
Definition:PassBuilderBindings.cpp:64
Path.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
STLExtras.h
This file contains some templates that are useful if you are working with the STL at all.
OS
raw_pwrite_stream & OS
Definition:SampleProfWriter.cpp:51
StringRef.h
Twine.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
T
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ArrayRef::end
iterator end() const
Definition:ArrayRef.h:157
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition:ArrayRef.h:168
llvm::ArrayRef::begin
iterator begin() const
Definition:ArrayRef.h:156
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition:ArrayRef.h:163
llvm::ArrayRef::data
const T * data() const
Definition:ArrayRef.h:165
llvm::ArrayRef::slice
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition:ArrayRef.h:198
llvm::DenseMapBase::lookup
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition:DenseMap.h:194
llvm::DenseMapBase::count
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition:DenseMap.h:152
llvm::DenseMap
Definition:DenseMap.h:727
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition:Error.h:608
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition:Error.h:578
llvm::MemoryBuffer::getBufferIdentifier
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
Definition:MemoryBuffer.h:76
llvm::MemoryBuffer::getBufferSize
size_t getBufferSize() const
Definition:MemoryBuffer.h:68
llvm::MemoryBuffer::getBuffer
StringRef getBuffer() const
Definition:MemoryBuffer.h:70
llvm::MemoryBuffer::getBufferStart
const char * getBufferStart() const
Definition:MemoryBuffer.h:66
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVectorTemplateCommon::end
iterator end()
Definition:SmallVector.h:269
llvm::SmallVectorTemplateCommon::front
reference front()
Definition:SmallVector.h:299
llvm::SmallVectorTemplateCommon::data
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition:SmallVector.h:286
llvm::SmallVectorTemplateCommon::begin
iterator begin()
Definition:SmallVector.h:267
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition:StringRef.h:700
llvm::StringRef::getAsInteger
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition:StringRef.h:470
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition:StringRef.h:229
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::drop_front
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition:StringRef.h:609
llvm::StringRef::slice
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition:StringRef.h:684
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition:StringRef.h:150
llvm::StringRef::data
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition:StringRef.h:144
llvm::StringRef::take_front
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition:StringRef.h:580
llvm::StringTableBuilder::getOffset
size_t getOffset(CachedHashStringRef S) const
Get the offest of a string in the string table.
Definition:StringTableBuilder.cpp:195
llvm::StringTableBuilder::write
void write(raw_ostream &OS) const
Definition:StringTableBuilder.cpp:61
llvm::StringTableBuilder::add
size_t add(CachedHashStringRef S)
Add a string to the builder.
Definition:StringTableBuilder.cpp:202
llvm::StringTableBuilder::finalize
void finalize()
Analyze the strings and build the final table.
Definition:StringTableBuilder.cpp:129
llvm::StringTableBuilder::getSize
size_t getSize() const
Definition:StringTableBuilder.h:80
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition:Twine.h:416
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::WritableMemoryBuffer
This class is an extension of MemoryBuffer, which allows copy-on-write access to the underlying conte...
Definition:MemoryBuffer.h:181
llvm::WritableMemoryBuffer::getNewMemBuffer
static std::unique_ptr< WritableMemoryBuffer > getNewMemBuffer(size_t Size, const Twine &BufferName="")
Allocate a new zero-initialized MemoryBuffer of the specified size.
Definition:MemoryBuffer.cpp:349
llvm::WritableMemoryBuffer::getBufferStart
char * getBufferStart()
Definition:MemoryBuffer.h:192
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition:STLFunctionalExtras.h:37
llvm::objcopy::elf::ASCIIHexWriter::checkSection
Error checkSection(const SectionBase &S) const
Definition:ELFObject.cpp:2764
llvm::objcopy::elf::ASCIIHexWriter::finalize
Error finalize() override
Definition:ELFObject.cpp:2774
llvm::objcopy::elf::ASCIIHexWriter::OutputFileName
StringRef OutputFileName
Definition:ELFObject.h:385
llvm::objcopy::elf::ASCIIHexWriter::Sections
std::vector< const SectionBase * > Sections
Definition:ELFObject.h:387
llvm::objcopy::elf::ASCIIHexWriter::getTotalSize
virtual Expected< size_t > getTotalSize(WritableMemoryBuffer &EmptyBuffer) const =0
llvm::objcopy::elf::ASCIIHexWriter::TotalSize
size_t TotalSize
Definition:ELFObject.h:386
llvm::objcopy::elf::BasicELFBuilder::addStrTab
StringTableSection * addStrTab()
Definition:ELFObject.cpp:1281
llvm::objcopy::elf::BasicELFBuilder::initFileHeader
void initFileHeader()
Definition:ELFObject.cpp:1269
llvm::objcopy::elf::BasicELFBuilder::initHeaderSegment
void initHeaderSegment()
Definition:ELFObject.cpp:1279
llvm::objcopy::elf::BasicELFBuilder::addSymTab
SymbolTableSection * addSymTab(StringTableSection *StrTab)
Definition:ELFObject.cpp:1289
llvm::objcopy::elf::BasicELFBuilder::Obj
std::unique_ptr< Object > Obj
Definition:ELFObject.h:1053
llvm::objcopy::elf::BasicELFBuilder::initSections
Error initSections()
Definition:ELFObject.cpp:1302
llvm::objcopy::elf::BinaryELFBuilder
Definition:ELFObject.h:1065
llvm::objcopy::elf::BinaryELFBuilder::build
Expected< std::unique_ptr< Object > > build()
Definition:ELFObject.cpp:1335
llvm::objcopy::elf::BinaryReader::create
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition:ELFObject.cpp:1954
llvm::objcopy::elf::BinarySectionWriter::visit
Error visit(const SymbolTableSection &Sec) override
Definition:ELFObject.cpp:164
llvm::objcopy::elf::BinaryWriter::finalize
Error finalize() override
Definition:ELFObject.cpp:2730
llvm::objcopy::elf::BinaryWriter::write
Error write() override
Definition:ELFObject.cpp:2692
llvm::objcopy::elf::CompressedSection
Definition:ELFObject.h:663
llvm::objcopy::elf::CompressedSection::accept
Error accept(SectionVisitor &Visitor) const override
Definition:ELFObject.cpp:581
llvm::objcopy::elf::CompressedSection::CompressedSection
CompressedSection(const SectionBase &Sec, DebugCompressionType CompressionType, bool Is64Bits)
Definition:ELFObject.cpp:557
llvm::objcopy::elf::DecompressedSection
Definition:ELFObject.h:690
llvm::objcopy::elf::DecompressedSection::accept
Error accept(SectionVisitor &Visitor) const override
Definition:ELFObject.cpp:502
llvm::objcopy::elf::DecompressedSection::ChType
uint32_t ChType
Definition:ELFObject.h:694
llvm::objcopy::elf::DynamicRelocationSection
Definition:ELFObject.h:1002
llvm::objcopy::elf::DynamicRelocationSection::accept
Error accept(SectionVisitor &) const override
Definition:ELFObject.cpp:1036
llvm::objcopy::elf::DynamicRelocationSection::removeSectionReferences
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition:ELFObject.cpp:1044
llvm::objcopy::elf::DynamicSection
Definition:ELFObject.h:992
llvm::objcopy::elf::DynamicSymbolTableSection
Definition:ELFObject.h:983
llvm::objcopy::elf::ELFBuilder
Definition:ELFObject.h:1088
llvm::objcopy::elf::ELFBuilder::ELFBuilder
ELFBuilder(const ELFObjectFile< ELFT > &ElfObj, Object &Obj, std::optional< StringRef > ExtractPartition)
Definition:ELFObject.cpp:1408
llvm::objcopy::elf::ELFBuilder::build
Error build(bool EnsureSymtab)
Definition:ELFObject.cpp:1920
llvm::objcopy::elf::ELFReader::create
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition:ELFObject.cpp:1993
llvm::objcopy::elf::ELFSectionSizer::visit
Error visit(Section &Sec) override
Definition:ELFObject.cpp:82
llvm::objcopy::elf::ELFSectionWriter::visit
Error visit(const SymbolTableSection &Sec) override
Definition:ELFObject.cpp:862
llvm::objcopy::elf::ELFWriter
Definition:ELFObject.h:324
llvm::objcopy::elf::ELFWriter::finalize
Error finalize() override
Definition:ELFObject.cpp:2576
llvm::objcopy::elf::ELFWriter::ELFWriter
ELFWriter(Object &Obj, raw_ostream &Out, bool WSH, bool OnlyKeepDebug)
Definition:ELFObject.cpp:2152
llvm::objcopy::elf::ELFWriter::write
Error write() override
Definition:ELFObject.cpp:2540
llvm::objcopy::elf::GnuDebugLinkSection
Definition:ELFObject.h:1024
llvm::objcopy::elf::GnuDebugLinkSection::accept
Error accept(SectionVisitor &Visitor) const override
Definition:ELFObject.cpp:1189
llvm::objcopy::elf::GnuDebugLinkSection::GnuDebugLinkSection
GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC)
Definition:ELFObject.cpp:1172
llvm::objcopy::elf::GroupSection
Definition:ELFObject.h:940
llvm::objcopy::elf::GroupSection::setSymTab
void setSymTab(const SymbolTableSection *SymTabSec)
Definition:ELFObject.h:957
llvm::objcopy::elf::GroupSection::setSymbol
void setSymbol(Symbol *S)
Definition:ELFObject.h:958
llvm::objcopy::elf::GroupSection::onRemove
void onRemove() override
Definition:ELFObject.cpp:1126
llvm::objcopy::elf::GroupSection::replaceSectionReferences
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition:ELFObject.cpp:1119
llvm::objcopy::elf::GroupSection::accept
Error accept(SectionVisitor &) const override
Definition:ELFObject.cpp:1207
llvm::objcopy::elf::GroupSection::markSymbols
void markSymbols() override
Definition:ELFObject.cpp:1114
llvm::objcopy::elf::GroupSection::Contents
ArrayRef< uint8_t > Contents
Definition:ELFObject.h:953
llvm::objcopy::elf::GroupSection::addMember
void addMember(SectionBase *Sec)
Definition:ELFObject.h:960
llvm::objcopy::elf::GroupSection::removeSectionReferences
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition:ELFObject.cpp:1089
llvm::objcopy::elf::GroupSection::setFlagWord
void setFlagWord(ELF::Elf32_Word W)
Definition:ELFObject.h:959
llvm::objcopy::elf::GroupSection::removeSymbols
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition:ELFObject.cpp:1105
llvm::objcopy::elf::GroupSection::finalize
void finalize() override
Definition:ELFObject.cpp:1078
llvm::objcopy::elf::IHexELFBuilder
Definition:ELFObject.h:1077
llvm::objcopy::elf::IHexELFBuilder::build
Expected< std::unique_ptr< Object > > build()
Definition:ELFObject.cpp:1395
llvm::objcopy::elf::IHexReader::create
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Definition:ELFObject.cpp:1985
llvm::objcopy::elf::IHexSectionWriterBase
Definition:ELFObject.h:271
llvm::objcopy::elf::IHexSectionWriterBase::writeSection
void writeSection(const SectionBase *Sec, ArrayRef< uint8_t > Data)
Definition:ELFObject.cpp:351
llvm::objcopy::elf::IHexSectionWriterBase::visit
Error visit(const Section &Sec) final
Definition:ELFObject.cpp:400
llvm::objcopy::elf::IHexSectionWriterBase::Offset
uint64_t Offset
Definition:ELFObject.h:284
llvm::objcopy::elf::IHexSectionWriterBase::writeData
virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
Definition:ELFObject.cpp:395
llvm::objcopy::elf::IHexSectionWriter
Definition:ELFObject.h:302
llvm::objcopy::elf::IHexSectionWriter::writeData
void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data) override
Definition:ELFObject.cpp:425
llvm::objcopy::elf::IHexSectionWriter::visit
Error visit(const StringTableSection &Sec) override
Definition:ELFObject.cpp:432
llvm::objcopy::elf::IHexWriter::write
Error write() override
Definition:ELFObject.cpp:2853
llvm::objcopy::elf::MutableSectionVisitor
Definition:ELFObject.h:90
llvm::objcopy::elf::MutableSectionVisitor::visit
virtual Error visit(Section &Sec)=0
llvm::objcopy::elf::Object
Definition:ELFObject.h:1157
llvm::objcopy::elf::Object::sections
SectionTableRef sections() const
Definition:ELFObject.h:1205
llvm::objcopy::elf::Object::SectionNames
StringTableSection * SectionNames
Definition:ELFObject.h:1199
llvm::objcopy::elf::Object::isRelocatable
bool isRelocatable() const
Definition:ELFObject.h:1244
llvm::objcopy::elf::Object::allocSections
iterator_range< filter_iterator< pointee_iterator< std::vector< SecPtr >::const_iterator >, decltype(&sectionIsAlloc)> > allocSections() const
Definition:ELFObject.h:1209
llvm::objcopy::elf::Object::updateSection
Error updateSection(StringRef Name, ArrayRef< uint8_t > Data)
Definition:ELFObject.cpp:2181
llvm::objcopy::elf::Object::SectionIndexTable
SectionIndexSection * SectionIndexTable
Definition:ELFObject.h:1201
llvm::objcopy::elf::Object::removeSymbols
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
Definition:ELFObject.cpp:2282
llvm::objcopy::elf::Object::IsMips64EL
bool IsMips64EL
Definition:ELFObject.h:1203
llvm::objcopy::elf::Object::removeSections
Error removeSections(bool AllowBrokenLinks, std::function< bool(const SectionBase &)> ToRemove)
Definition:ELFObject.cpp:2197
llvm::objcopy::elf::Object::SymbolTable
SymbolTableSection * SymbolTable
Definition:ELFObject.h:1200
llvm::objcopy::elf::Object::addNewSymbolTable
Error addNewSymbolTable()
Definition:ELFObject.cpp:2290
llvm::objcopy::elf::Object::Entry
uint64_t Entry
Definition:ELFObject.h:1190
llvm::objcopy::elf::Object::replaceSections
Error replaceSections(const DenseMap< SectionBase *, SectionBase * > &FromTo)
Definition:ELFObject.cpp:2258
llvm::objcopy::elf::OwnedDataSection
Definition:ELFObject.h:628
llvm::objcopy::elf::OwnedDataSection::appendHexData
void appendHexData(StringRef HexData)
Definition:ELFObject.cpp:518
llvm::objcopy::elf::OwnedDataSection::accept
Error accept(SectionVisitor &Sec) const override
Definition:ELFObject.cpp:510
llvm::objcopy::elf::Reader::~Reader
virtual ~Reader()
llvm::objcopy::elf::RelocSectionWithSymtabBase::finalize
void finalize() override
Definition:ELFObject.cpp:957
llvm::objcopy::elf::RelocSectionWithSymtabBase::initialize
Error initialize(SectionTableRef SecTable) override
Definition:ELFObject.cpp:927
llvm::objcopy::elf::RelocSectionWithSymtabBase< SymbolTableSection >::Symbols
SymbolTableSection * Symbols
Definition:ELFObject.h:902
llvm::objcopy::elf::RelocationSectionBase::SecToApplyRel
SectionBase * SecToApplyRel
Definition:ELFObject.h:879
llvm::objcopy::elf::RelocationSectionBase::getNamePrefix
StringRef getNamePrefix() const
Definition:ELFObject.cpp:886
llvm::objcopy::elf::RelocationSection
Definition:ELFObject.h:910
llvm::objcopy::elf::RelocationSection::markSymbols
void markSymbols() override
Definition:ELFObject.cpp:1018
llvm::objcopy::elf::RelocationSection::getObject
const Object & getObject() const
Definition:ELFObject.h:928
llvm::objcopy::elf::RelocationSection::addRelocation
void addRelocation(const Relocation &Rel)
Definition:ELFObject.h:918
llvm::objcopy::elf::RelocationSection::accept
Error accept(SectionVisitor &Visitor) const override
Definition:ELFObject.cpp:999
llvm::objcopy::elf::RelocationSection::removeSymbols
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition:ELFObject.cpp:1007
llvm::objcopy::elf::RelocationSection::replaceSectionReferences
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition:ELFObject.cpp:1024
llvm::objcopy::elf::RelocationSection::removeSectionReferences
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition:ELFObject.cpp:899
llvm::objcopy::elf::SRECSectionWriterBase::Type
uint8_t Type
Definition:ELFObject.h:481
llvm::objcopy::elf::SRECSectionWriterBase::HeaderSize
uint64_t HeaderSize
Definition:ELFObject.h:479
llvm::objcopy::elf::SRECSectionWriterBase::Records
std::vector< SRecord > Records
Definition:ELFObject.h:482
llvm::objcopy::elf::SRECSectionWriterBase::writeRecord
virtual void writeRecord(SRecord &Record, uint64_t Off)=0
llvm::objcopy::elf::SRECSectionWriterBase::Offset
uint64_t Offset
Definition:ELFObject.h:477
llvm::objcopy::elf::SRECSectionWriterBase::writeSection
void writeSection(const SectionBase &S, ArrayRef< uint8_t > Data)
Definition:ELFObject.cpp:2917
llvm::objcopy::elf::SRECSectionWriterBase::visit
Error visit(const Section &S) override
Definition:ELFObject.cpp:2884
llvm::objcopy::elf::SRECSectionWriterBase::writeRecords
void writeRecords(uint32_t Entry)
Definition:ELFObject.cpp:2904
llvm::objcopy::elf::SRECSectionWriter
Definition:ELFObject.h:499
llvm::objcopy::elf::SRECSectionWriter::visit
Error visit(const StringTableSection &Sec) override
Definition:ELFObject.cpp:2932
llvm::objcopy::elf::SRECSectionWriter::writeRecord
void writeRecord(SRecord &Record, uint64_t Off) override
Definition:ELFObject.cpp:2899
llvm::objcopy::elf::SRECSizeCalculator
Definition:ELFObject.h:490
llvm::objcopy::elf::SRECWriter::write
Error write() override
Definition:ELFObject.cpp:3047
llvm::objcopy::elf::SectionBase
Definition:ELFObject.h:509
llvm::objcopy::elf::SectionBase::markSymbols
virtual void markSymbols()
Definition:ELFObject.cpp:61
llvm::objcopy::elf::SectionBase::OriginalOffset
uint64_t OriginalOffset
Definition:ELFObject.h:519
llvm::objcopy::elf::SectionBase::OriginalData
ArrayRef< uint8_t > OriginalData
Definition:ELFObject.h:531
llvm::objcopy::elf::SectionBase::HasSymbol
bool HasSymbol
Definition:ELFObject.h:532
llvm::objcopy::elf::SectionBase::initialize
virtual Error initialize(SectionTableRef SecTable)
Definition:ELFObject.cpp:59
llvm::objcopy::elf::SectionBase::removeSectionReferences
virtual Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove)
Definition:ELFObject.cpp:50
llvm::objcopy::elf::SectionBase::Type
uint64_t Type
Definition:ELFObject.h:530
llvm::objcopy::elf::SectionBase::replaceSectionReferences
virtual void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &)
Definition:ELFObject.cpp:62
llvm::objcopy::elf::SectionBase::HeaderOffset
uint64_t HeaderOffset
Definition:ELFObject.h:513
llvm::objcopy::elf::SectionBase::ParentSegment
Segment * ParentSegment
Definition:ELFObject.h:512
llvm::objcopy::elf::SectionBase::Flags
uint64_t Flags
Definition:ELFObject.h:524
llvm::objcopy::elf::SectionBase::Name
std::string Name
Definition:ELFObject.h:511
llvm::objcopy::elf::SectionBase::Link
uint64_t Link
Definition:ELFObject.h:526
llvm::objcopy::elf::SectionBase::Size
uint64_t Size
Definition:ELFObject.h:529
llvm::objcopy::elf::SectionBase::OriginalType
uint64_t OriginalType
Definition:ELFObject.h:518
llvm::objcopy::elf::SectionBase::Align
uint64_t Align
Definition:ELFObject.h:522
llvm::objcopy::elf::SectionBase::onRemove
virtual void onRemove()
Definition:ELFObject.cpp:64
llvm::objcopy::elf::SectionBase::EntrySize
uint32_t EntrySize
Definition:ELFObject.h:523
llvm::objcopy::elf::SectionBase::Offset
uint64_t Offset
Definition:ELFObject.h:528
llvm::objcopy::elf::SectionBase::Info
uint64_t Info
Definition:ELFObject.h:525
llvm::objcopy::elf::SectionBase::OriginalFlags
uint64_t OriginalFlags
Definition:ELFObject.h:517
llvm::objcopy::elf::SectionBase::Addr
uint64_t Addr
Definition:ELFObject.h:521
llvm::objcopy::elf::SectionBase::finalize
virtual void finalize()
Definition:ELFObject.cpp:60
llvm::objcopy::elf::SectionBase::NameIndex
uint64_t NameIndex
Definition:ELFObject.h:527
llvm::objcopy::elf::SectionBase::Index
uint32_t Index
Definition:ELFObject.h:514
llvm::objcopy::elf::SectionBase::removeSymbols
virtual Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
Definition:ELFObject.cpp:55
llvm::objcopy::elf::SectionBase::accept
virtual Error accept(SectionVisitor &Visitor) const =0
llvm::objcopy::elf::SectionIndexSection
Definition:ELFObject.h:779
llvm::objcopy::elf::SectionIndexSection::addIndex
void addIndex(uint32_t Index)
Definition:ELFObject.h:788
llvm::objcopy::elf::SectionIndexSection::finalize
void finalize() override
Definition:ELFObject.cpp:638
llvm::objcopy::elf::SectionIndexSection::setSymTab
void setSymTab(SymbolTableSection *SymTab)
Definition:ELFObject.h:797
llvm::objcopy::elf::SectionIndexSection::accept
Error accept(SectionVisitor &Visitor) const override
Definition:ELFObject.cpp:640
llvm::objcopy::elf::SectionIndexSection::reserve
void reserve(size_t NumSymbols)
Definition:ELFObject.h:793
llvm::objcopy::elf::SectionIndexSection::initialize
Error initialize(SectionTableRef SecTable) override
Definition:ELFObject.cpp:621
llvm::objcopy::elf::SectionTableRef
Definition:ELFObject.h:50
llvm::objcopy::elf::SectionTableRef::getSectionOfType
Expected< T * > getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg)
Definition:ELFObject.cpp:1690
llvm::objcopy::elf::SectionTableRef::getSection
Expected< SectionBase * > getSection(uint32_t Index, Twine ErrMsg)
Definition:ELFObject.cpp:1682
llvm::objcopy::elf::SectionTableRef::size
size_t size() const
Definition:ELFObject.h:62
llvm::objcopy::elf::SectionVisitor
Definition:ELFObject.h:73
llvm::objcopy::elf::SectionVisitor::visit
virtual Error visit(const Section &Sec)=0
llvm::objcopy::elf::SectionWriter::visit
Error visit(const Section &Sec) override
Definition:ELFObject.cpp:186
llvm::objcopy::elf::SectionWriter::Out
WritableMemoryBuffer & Out
Definition:ELFObject.h:109
llvm::objcopy::elf::Section
Definition:ELFObject.h:603
llvm::objcopy::elf::Section::removeSectionReferences
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition:ELFObject.cpp:1064
llvm::objcopy::elf::Section::initialize
Error initialize(SectionTableRef SecTable) override
Definition:ELFObject.cpp:1133
llvm::objcopy::elf::Section::restoreSymTabLink
void restoreSymTabLink(SymbolTableSection &SymTab) override
Definition:ELFObject.cpp:448
llvm::objcopy::elf::Section::finalize
void finalize() override
Definition:ELFObject.cpp:1153
llvm::objcopy::elf::Section::accept
Error accept(SectionVisitor &Visitor) const override
Definition:ELFObject.cpp:440
llvm::objcopy::elf::Segment
Definition:ELFObject.h:559
llvm::objcopy::elf::Segment::addSection
void addSection(const SectionBase *Sec)
Definition:ELFObject.h:598
llvm::objcopy::elf::Segment::PAddr
uint64_t PAddr
Definition:ELFObject.h:577
llvm::objcopy::elf::Segment::ParentSegment
Segment * ParentSegment
Definition:ELFObject.h:584
llvm::objcopy::elf::Segment::Type
uint32_t Type
Definition:ELFObject.h:573
llvm::objcopy::elf::Segment::FileSize
uint64_t FileSize
Definition:ELFObject.h:578
llvm::objcopy::elf::Segment::Index
uint32_t Index
Definition:ELFObject.h:582
llvm::objcopy::elf::Segment::removeSection
void removeSection(const SectionBase *Sec)
Definition:ELFObject.h:597
llvm::objcopy::elf::Segment::firstSection
const SectionBase * firstSection() const
Definition:ELFObject.h:591
llvm::objcopy::elf::Segment::Align
uint64_t Align
Definition:ELFObject.h:580
llvm::objcopy::elf::Segment::OriginalOffset
uint64_t OriginalOffset
Definition:ELFObject.h:583
llvm::objcopy::elf::Segment::VAddr
uint64_t VAddr
Definition:ELFObject.h:576
llvm::objcopy::elf::Segment::MemSize
uint64_t MemSize
Definition:ELFObject.h:579
llvm::objcopy::elf::Segment::Offset
uint64_t Offset
Definition:ELFObject.h:575
llvm::objcopy::elf::Segment::getContents
ArrayRef< uint8_t > getContents() const
Definition:ELFObject.h:600
llvm::objcopy::elf::Segment::Flags
uint32_t Flags
Definition:ELFObject.h:574
llvm::objcopy::elf::Segment::Sections
std::set< const SectionBase *, SectionCompare > Sections
Definition:ELFObject.h:586
llvm::objcopy::elf::StringTableSection
Definition:ELFObject.h:714
llvm::objcopy::elf::StringTableSection::addString
void addString(StringRef Name)
Definition:ELFObject.cpp:589
llvm::objcopy::elf::StringTableSection::prepareForLayout
void prepareForLayout()
Definition:ELFObject.cpp:595
llvm::objcopy::elf::StringTableSection::findIndex
uint32_t findIndex(StringRef Name) const
Definition:ELFObject.cpp:591
llvm::objcopy::elf::StringTableSection::accept
Error accept(SectionVisitor &Visitor) const override
Definition:ELFObject.cpp:606
llvm::objcopy::elf::SymbolTableSection
Definition:ELFObject.h:811
llvm::objcopy::elf::SymbolTableSection::getStrTab
const SectionBase * getStrTab() const
Definition:ELFObject.h:840
llvm::objcopy::elf::SymbolTableSection::removeSectionReferences
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Definition:ELFObject.cpp:739
llvm::objcopy::elf::SymbolTableSection::getShndxTable
const SectionIndexSection * getShndxTable() const
Definition:ELFObject.h:838
llvm::objcopy::elf::SymbolTableSection::Symbols
std::vector< std::unique_ptr< Symbol > > Symbols
Definition:ELFObject.h:818
llvm::objcopy::elf::SymbolTableSection::SectionIndexTable
SectionIndexSection * SectionIndexTable
Definition:ELFObject.h:820
llvm::objcopy::elf::SymbolTableSection::accept
Error accept(SectionVisitor &Visitor) const override
Definition:ELFObject.cpp:878
llvm::objcopy::elf::SymbolTableSection::empty
bool empty() const
Definition:ELFObject.h:833
llvm::objcopy::elf::SymbolTableSection::addSymbol
void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility, uint16_t Shndx, uint64_t SymbolSize)
Definition:ELFObject.cpp:714
llvm::objcopy::elf::SymbolTableSection::updateSymbols
void updateSymbols(function_ref< void(Symbol &)> Callable)
Definition:ELFObject.cpp:756
llvm::objcopy::elf::SymbolTableSection::finalize
void finalize() override
Definition:ELFObject.cpp:802
llvm::objcopy::elf::SymbolTableSection::getSymbolByIndex
Expected< const Symbol * > getSymbolByIndex(uint32_t Index) const
Definition:ELFObject.cpp:845
llvm::objcopy::elf::SymbolTableSection::fillShndxTable
void fillShndxTable()
Definition:ELFObject.cpp:831
llvm::objcopy::elf::SymbolTableSection::removeSymbols
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Definition:ELFObject.cpp:765
llvm::objcopy::elf::SymbolTableSection::prepareForLayout
void prepareForLayout()
Definition:ELFObject.cpp:815
llvm::objcopy::elf::SymbolTableSection::IndicesChanged
bool IndicesChanged
Definition:ELFObject.h:821
llvm::objcopy::elf::SymbolTableSection::initialize
Error initialize(SectionTableRef SecTable) override
Definition:ELFObject.cpp:786
llvm::objcopy::elf::SymbolTableSection::replaceSectionReferences
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Definition:ELFObject.cpp:779
llvm::objcopy::elf::SymbolTableSection::SymPtr
std::unique_ptr< Symbol > SymPtr
Definition:ELFObject.h:823
llvm::objcopy::elf::SymbolTableSection::setShndxTable
void setShndxTable(SectionIndexSection *ShndxTable)
Definition:ELFObject.h:835
llvm::objcopy::elf::SymbolTableSection::SymbolNames
StringTableSection * SymbolNames
Definition:ELFObject.h:819
llvm::objcopy::elf::Writer
Definition:ELFObject.h:310
llvm::objcopy::elf::Writer::Out
raw_ostream & Out
Definition:ELFObject.h:314
llvm::objcopy::elf::Writer::~Writer
virtual ~Writer()
llvm::objcopy::elf::Writer::Obj
Object & Obj
Definition:ELFObject.h:312
llvm::objcopy::elf::Writer::Buf
std::unique_ptr< WritableMemoryBuffer > Buf
Definition:ELFObject.h:313
llvm::object::ELFFile
Definition:ELF.h:255
llvm::object::ELFFile::getHeader
const Elf_Ehdr & getHeader() const
Definition:ELF.h:279
llvm::object::ELFFile::create
static Expected< ELFFile > create(StringRef Object)
Definition:ELF.h:888
llvm::object::ELFFile::program_headers
Expected< Elf_Phdr_Range > program_headers() const
Iterate over program header table.
Definition:ELF.h:376
llvm::object::ELFFile::getBufSize
size_t getBufSize() const
Definition:ELF.h:269
llvm::object::ELFFile::base
const uint8_t * base() const
Definition:ELF.h:266
llvm::object::ELFObjectFile
Definition:ELFObjectFile.h:265
llvm::object::Record
Represents a GOFF physical record.
Definition:GOFF.h:31
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition:raw_ostream.h:52
llvm::raw_ostream::write
raw_ostream & write(unsigned char C)
Definition:raw_ostream.cpp:225
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition:raw_ostream.h:691
uint16_t
uint32_t
uint64_t
uint8_t
iterator_range.h
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
UINT64_MAX
#define UINT64_MAX
Definition:DataTypes.h:77
ErrorHandling.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::ELF
Definition:ELF.h:28
llvm::ELF::ELFOSABI_NONE
@ ELFOSABI_NONE
Definition:ELF.h:344
llvm::ELF::SHN_XINDEX
@ SHN_XINDEX
Definition:ELF.h:1091
llvm::ELF::SHN_ABS
@ SHN_ABS
Definition:ELF.h:1089
llvm::ELF::SHN_COMMON
@ SHN_COMMON
Definition:ELF.h:1090
llvm::ELF::SHN_UNDEF
@ SHN_UNDEF
Definition:ELF.h:1083
llvm::ELF::SHN_LORESERVE
@ SHN_LORESERVE
Definition:ELF.h:1084
llvm::ELF::encodeCrel
void encodeCrel(raw_ostream &OS, RelocsTy Relocs, F ToCrel)
Definition:MCELFExtras.h:25
llvm::ELF::ELFCLASS64
@ ELFCLASS64
Definition:ELF.h:332
llvm::ELF::ELFCLASS32
@ ELFCLASS32
Definition:ELF.h:331
llvm::ELF::EI_DATA
@ EI_DATA
Definition:ELF.h:54
llvm::ELF::EI_MAG3
@ EI_MAG3
Definition:ELF.h:52
llvm::ELF::EI_MAG1
@ EI_MAG1
Definition:ELF.h:50
llvm::ELF::EI_VERSION
@ EI_VERSION
Definition:ELF.h:55
llvm::ELF::EI_MAG2
@ EI_MAG2
Definition:ELF.h:51
llvm::ELF::EI_ABIVERSION
@ EI_ABIVERSION
Definition:ELF.h:57
llvm::ELF::EI_MAG0
@ EI_MAG0
Definition:ELF.h:49
llvm::ELF::EI_CLASS
@ EI_CLASS
Definition:ELF.h:53
llvm::ELF::EI_OSABI
@ EI_OSABI
Definition:ELF.h:56
llvm::ELF::EV_CURRENT
@ EV_CURRENT
Definition:ELF.h:128
llvm::ELF::EM_NONE
@ EM_NONE
Definition:ELF.h:136
llvm::ELF::EM_HEXAGON
@ EM_HEXAGON
Definition:ELF.h:260
llvm::ELF::EM_MIPS
@ EM_MIPS
Definition:ELF.h:144
llvm::ELF::EM_AMDGPU
@ EM_AMDGPU
Definition:ELF.h:319
llvm::ELF::Elf32_Word
uint32_t Elf32_Word
Definition:ELF.h:33
llvm::ELF::SHT_STRTAB
@ SHT_STRTAB
Definition:ELF.h:1100
llvm::ELF::SHT_GROUP
@ SHT_GROUP
Definition:ELF.h:1112
llvm::ELF::SHT_PROGBITS
@ SHT_PROGBITS
Definition:ELF.h:1098
llvm::ELF::SHT_REL
@ SHT_REL
Definition:ELF.h:1106
llvm::ELF::SHT_NULL
@ SHT_NULL
Definition:ELF.h:1097
llvm::ELF::SHT_NOBITS
@ SHT_NOBITS
Definition:ELF.h:1105
llvm::ELF::SHT_SYMTAB
@ SHT_SYMTAB
Definition:ELF.h:1099
llvm::ELF::SHT_LLVM_PART_EHDR
@ SHT_LLVM_PART_EHDR
Definition:ELF.h:1132
llvm::ELF::SHT_CREL
@ SHT_CREL
Definition:ELF.h:1119
llvm::ELF::SHT_DYNAMIC
@ SHT_DYNAMIC
Definition:ELF.h:1103
llvm::ELF::SHT_SYMTAB_SHNDX
@ SHT_SYMTAB_SHNDX
Definition:ELF.h:1113
llvm::ELF::SHT_GNU_HASH
@ SHT_GNU_HASH
Definition:ELF.h:1146
llvm::ELF::SHT_RELA
@ SHT_RELA
Definition:ELF.h:1101
llvm::ELF::SHT_DYNSYM
@ SHT_DYNSYM
Definition:ELF.h:1108
llvm::ELF::SHT_HASH
@ SHT_HASH
Definition:ELF.h:1102
llvm::ELF::ELFCOMPRESS_ZSTD
@ ELFCOMPRESS_ZSTD
Definition:ELF.h:1985
llvm::ELF::ELFCOMPRESS_ZLIB
@ ELFCOMPRESS_ZLIB
Definition:ELF.h:1984
llvm::ELF::SHN_HEXAGON_SCOMMON_2
@ SHN_HEXAGON_SCOMMON_2
Definition:ELF.h:662
llvm::ELF::SHN_HEXAGON_SCOMMON_4
@ SHN_HEXAGON_SCOMMON_4
Definition:ELF.h:663
llvm::ELF::SHN_HEXAGON_SCOMMON_8
@ SHN_HEXAGON_SCOMMON_8
Definition:ELF.h:664
llvm::ELF::SHN_HEXAGON_SCOMMON_1
@ SHN_HEXAGON_SCOMMON_1
Definition:ELF.h:661
llvm::ELF::SHN_HEXAGON_SCOMMON
@ SHN_HEXAGON_SCOMMON
Definition:ELF.h:660
llvm::ELF::SHF_ALLOC
@ SHF_ALLOC
Definition:ELF.h:1198
llvm::ELF::SHF_COMPRESSED
@ SHF_COMPRESSED
Definition:ELF.h:1226
llvm::ELF::SHF_WRITE
@ SHF_WRITE
Definition:ELF.h:1195
llvm::ELF::SHF_TLS
@ SHF_TLS
Definition:ELF.h:1223
llvm::ELF::STB_GLOBAL
@ STB_GLOBAL
Definition:ELF.h:1352
llvm::ELF::STB_LOCAL
@ STB_LOCAL
Definition:ELF.h:1351
llvm::ELF::PT_LOAD
@ PT_LOAD
Definition:ELF.h:1505
llvm::ELF::PT_TLS
@ PT_TLS
Definition:ELF.h:1511
llvm::ELF::PT_PHDR
@ PT_PHDR
Definition:ELF.h:1510
llvm::ELF::ET_REL
@ ET_REL
Definition:ELF.h:117
llvm::ELF::STT_NOTYPE
@ STT_NOTYPE
Definition:ELF.h:1363
llvm::ELF::ELFDATA2MSB
@ ELFDATA2MSB
Definition:ELF.h:339
llvm::ELF::ELFDATA2LSB
@ ELFDATA2LSB
Definition:ELF.h:338
llvm::ELF::GRP_COMDAT
@ GRP_COMDAT
Definition:ELF.h:1298
llvm::ELF::SHN_AMDGPU_LDS
@ SHN_AMDGPU_LDS
Definition:ELF.h:1906
llvm::ELF::SHN_MIPS_SUNDEFINED
@ SHN_MIPS_SUNDEFINED
Definition:ELF.h:580
llvm::ELF::SHN_MIPS_SCOMMON
@ SHN_MIPS_SCOMMON
Definition:ELF.h:579
llvm::ELF::SHN_MIPS_ACOMMON
@ SHN_MIPS_ACOMMON
Definition:ELF.h:576
llvm::MCID::Terminator
@ Terminator
Definition:MCInstrDesc.h:158
llvm::compression::getReasonIfUnsupported
const char * getReasonIfUnsupported(Format F)
Definition:Compression.cpp:30
llvm::compression::decompress
Error decompress(DebugCompressionType T, ArrayRef< uint8_t > Input, uint8_t *Output, size_t UncompressedSize)
Definition:Compression.cpp:58
llvm::compression::formatFor
Format formatFor(DebugCompressionType Type)
Definition:Compression.h:81
llvm::compression::compress
void compress(Params P, ArrayRef< uint8_t > Input, SmallVectorImpl< uint8_t > &Output)
Definition:Compression.cpp:46
llvm::dwarf::Index
Index
Definition:Dwarf.h:882
llvm::irsymtab::storage::Word
support::ulittle32_t Word
Definition:IRSymtab.h:52
llvm::objcopy::elf
Definition:ELFObjcopy.h:25
llvm::objcopy::elf::SymbolShndxType
SymbolShndxType
Definition:ELFObject.h:741
llvm::objcopy::elf::SYMBOL_LOOS
@ SYMBOL_LOOS
Definition:ELFObject.h:757
llvm::objcopy::elf::SYMBOL_LOPROC
@ SYMBOL_LOPROC
Definition:ELFObject.h:745
llvm::objcopy::elf::SYMBOL_COMMON
@ SYMBOL_COMMON
Definition:ELFObject.h:744
llvm::objcopy::elf::SYMBOL_SIMPLE_INDEX
@ SYMBOL_SIMPLE_INDEX
Definition:ELFObject.h:742
llvm::objcopy::elf::SYMBOL_ABS
@ SYMBOL_ABS
Definition:ELFObject.h:743
llvm::objcopy::elf::SYMBOL_HIPROC
@ SYMBOL_HIPROC
Definition:ELFObject.h:756
llvm::objcopy::elf::SYMBOL_HIOS
@ SYMBOL_HIOS
Definition:ELFObject.h:758
llvm::objcopy::SymbolFlag::File
@ File
llvm::objcopy::DiscardType::None
@ None
llvm::object
Definition:DWARFDebugLoc.h:24
llvm::sampleprof::Base
@ Base
Definition:Discriminator.h:58
llvm::support::endian::write
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition:Endian.h:92
llvm::support
Definition:Endian.h:26
llvm::sys::path::filename
StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition:Path.cpp:577
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::drop_begin
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition:STLExtras.h:329
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::stable_sort
void stable_sort(R &&Range)
Definition:STLExtras.h:2037
llvm::size
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition:STLExtras.h:1697
llvm::dyn_cast
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition:Casting.h:649
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition:iterator_range.h:77
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition:Error.h:1291
llvm::errc::operation_not_permitted
@ operation_not_permitted
llvm::errc::not_enough_memory
@ not_enough_memory
llvm::errc::invalid_argument
@ invalid_argument
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition:STLExtras.h:1746
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition:STLExtras.h:1664
llvm::is_sorted
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition:STLExtras.h:1926
llvm::CaptureComponents::Address
@ Address
llvm::ModRefInfo::Mod
@ Mod
The access may modify the value stored in memory.
llvm::DebugCompressionType
DebugCompressionType
Definition:Compression.h:27
llvm::DebugCompressionType::Zstd
@ Zstd
Zstandard.
llvm::DebugCompressionType::None
@ None
No compression.
llvm::DebugCompressionType::Zlib
@ Zlib
zlib
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition:Alignment.h:155
llvm::copy
OutputIt copy(R &&Range, OutputIt Out)
Definition:STLExtras.h:1841
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition:STLExtras.h:1766
llvm::erase_if
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition:STLExtras.h:2099
llvm::toString
const char * toString(DWARFSectionKind Kind)
Definition:DWARFUnitIndex.h:67
llvm::endianness::big
@ big
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition:Alignment.h:39
llvm::ELF::Elf_Crel
Definition:ELF.h:1468
llvm::compression::Params
Definition:Compression.h:93
llvm::objcopy::elf::IHexRecord
Definition:ELFObject.h:199
llvm::objcopy::elf::IHexRecord::Type
Type
Definition:ELFObject.h:233
llvm::objcopy::elf::IHexRecord::StartAddr
@ StartAddr
Definition:ELFObject.h:262
llvm::objcopy::elf::IHexRecord::StartAddr80x86
@ StartAddr80x86
Definition:ELFObject.h:253
llvm::objcopy::elf::IHexRecord::EndOfFile
@ EndOfFile
Definition:ELFObject.h:240
llvm::objcopy::elf::IHexRecord::Data
@ Data
Definition:ELFObject.h:236
llvm::objcopy::elf::IHexRecord::SegmentAddr
@ SegmentAddr
Definition:ELFObject.h:248
llvm::objcopy::elf::IHexRecord::ExtendedAddr
@ ExtendedAddr
Definition:ELFObject.h:258
llvm::objcopy::elf::IHexRecord::Addr
uint16_t Addr
Definition:ELFObject.h:201
llvm::objcopy::elf::IHexRecord::getLine
static IHexLineData getLine(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
Definition:ELFObject.cpp:232
llvm::objcopy::elf::IHexRecord::getChecksum
static uint8_t getChecksum(StringRef S)
Definition:ELFObject.cpp:222
llvm::objcopy::elf::IHexRecord::parse
static Expected< IHexRecord > parse(StringRef Line)
Definition:ELFObject.cpp:314
llvm::objcopy::elf::IHexRecord::getLength
static size_t getLength(size_t DataSize)
Definition:ELFObject.h:209
llvm::objcopy::elf::IHexRecord::getLineLength
static size_t getLineLength(size_t DataSize)
Definition:ELFObject.h:215
llvm::objcopy::elf::IHexRecord::HexData
StringRef HexData
Definition:ELFObject.h:205
llvm::objcopy::elf::Relocation
Definition:ELFObject.h:861
llvm::objcopy::elf::Relocation::Addend
uint64_t Addend
Definition:ELFObject.h:864
llvm::objcopy::elf::Relocation::RelocSymbol
Symbol * RelocSymbol
Definition:ELFObject.h:862
llvm::objcopy::elf::Relocation::Type
uint32_t Type
Definition:ELFObject.h:865
llvm::objcopy::elf::Relocation::Offset
uint64_t Offset
Definition:ELFObject.h:863
llvm::objcopy::elf::SRecord
Definition:ELFObject.h:421
llvm::objcopy::elf::SRecord::Address
uint32_t Address
Definition:ELFObject.h:423
llvm::objcopy::elf::SRecord::getSize
size_t getSize() const
Definition:ELFObject.cpp:2972
llvm::objcopy::elf::SRecord::getAddressSize
uint8_t getAddressSize() const
Definition:ELFObject.cpp:2977
llvm::objcopy::elf::SRecord::Type
Type
Definition:ELFObject.h:434
llvm::objcopy::elf::SRecord::S8
@ S8
Definition:ELFObject.h:452
llvm::objcopy::elf::SRecord::S1
@ S1
Definition:ELFObject.h:438
llvm::objcopy::elf::SRecord::S2
@ S2
Definition:ELFObject.h:440
llvm::objcopy::elf::SRecord::S3
@ S3
Definition:ELFObject.h:442
llvm::objcopy::elf::SRecord::S7
@ S7
Definition:ELFObject.h:450
llvm::objcopy::elf::SRecord::S0
@ S0
Definition:ELFObject.h:436
llvm::objcopy::elf::SRecord::S9
@ S9
Definition:ELFObject.h:454
llvm::objcopy::elf::SRecord::getHeader
static SRecord getHeader(StringRef FileName)
Definition:ELFObject.cpp:3006
llvm::objcopy::elf::SRecord::getChecksum
uint8_t getChecksum() const
Definition:ELFObject.cpp:2961
llvm::objcopy::elf::SRecord::getCount
uint8_t getCount() const
Definition:ELFObject.cpp:2992
llvm::objcopy::elf::SRecord::toString
SRecLineData toString() const
Definition:ELFObject.cpp:2941
llvm::objcopy::elf::SRecord::getType
static uint8_t getType(uint32_t Address)
Definition:ELFObject.cpp:2998
llvm::objcopy::elf::SRecord::Data
ArrayRef< uint8_t > Data
Definition:ELFObject.h:424
llvm::objcopy::elf::Symbol
Definition:ELFObject.h:762
llvm::objcopy::elf::Symbol::Type
uint8_t Type
Definition:ELFObject.h:770
llvm::objcopy::elf::Symbol::isCommon
bool isCommon() const
Definition:ELFObject.cpp:703
llvm::objcopy::elf::Symbol::Size
uint64_t Size
Definition:ELFObject.h:769
llvm::objcopy::elf::Symbol::getShndx
uint16_t getShndx() const
Definition:ELFObject.cpp:684
llvm::objcopy::elf::Symbol::Name
std::string Name
Definition:ELFObject.h:767
llvm::objcopy::elf::Symbol::Visibility
uint8_t Visibility
Definition:ELFObject.h:772
llvm::objcopy::elf::Symbol::NameIndex
uint32_t NameIndex
Definition:ELFObject.h:768
llvm::objcopy::elf::Symbol::DefinedIn
SectionBase * DefinedIn
Definition:ELFObject.h:764
llvm::objcopy::elf::Symbol::Binding
uint8_t Binding
Definition:ELFObject.h:763
llvm::objcopy::elf::Symbol::Value
uint64_t Value
Definition:ELFObject.h:771
llvm::objcopy::elf::Symbol::ShndxType
SymbolShndxType ShndxType
Definition:ELFObject.h:765
llvm::objcopy::elf::Symbol::Referenced
bool Referenced
Definition:ELFObject.h:773
llvm::objcopy::elf::Symbol::Index
uint32_t Index
Definition:ELFObject.h:766
llvm::object::Elf_Chdr_Impl
Definition:ELFTypes.h:43
llvm::object::Elf_Rel_Impl
Definition:ELFTypes.h:34
parse
Definition:regcomp.c:192

Generated on Sun Jul 20 2025 09:45:23 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp