LLVM: lib/ObjCopy/ELF/ELFObjcopy.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
32#include
33#include
34#include
35#include
36#include
37#include
38#include <system_error>
39#include
40
41using namespace llvm;
46
48
51}
52
55}
56
58
60 return false;
61
62
64}
65
69 if (AllFlags & SectionFlag::SecAlloc)
71 if (!(AllFlags & SectionFlag::SecReadonly))
73 if (AllFlags & SectionFlag::SecCode)
75 if (AllFlags & SectionFlag::SecMerge)
77 if (AllFlags & SectionFlag::SecStrings)
79 if (AllFlags & SectionFlag::SecExclude)
81 if (AllFlags & SectionFlag::SecLarge) {
84 "section flag SHF_X86_64_LARGE can only be used "
85 "with x86_64 architecture");
87 }
88 return NewFlags;
89}
90
94
95
102 return (OldFlags & PreserveMask) | (NewFlags & ~PreserveMask);
103}
104
106
107
111}
112
116 if (!NewFlags)
119
120
121
122
125 Flags & (SectionFlag::SecContents | SectionFlag::SecLoad)))
127
129}
130
132
142}
143
145
146 if (MI.Is64Bit)
148 else
150}
151
155
156 switch (OutputElfType) {
158 return std::make_unique<ELFWriter>(Obj, Out, .StripSections,
159 Config.OnlyKeepDebug);
161 return std::make_unique<ELFWriter>(Obj, Out, .StripSections,
162 Config.OnlyKeepDebug);
164 return std::make_unique<ELFWriter>(Obj, Out, .StripSections,
165 Config.OnlyKeepDebug);
167 return std::make_unique<ELFWriter>(Obj, Out, .StripSections,
168 Config.OnlyKeepDebug);
169 }
171}
172
176 switch (Config.OutputFormat) {
177 case FileFormat::Binary:
178 return std::make_unique(Obj, Out, Config);
179 case FileFormat::IHex:
180 return std::make_unique(Obj, Out, Config.OutputFilename);
181 case FileFormat::SREC:
182 return std::make_unique(Obj, Out, Config.OutputFilename);
183 default:
185 }
186}
187
190 for (auto &Sec : Obj.sections()) {
191 if (Sec.Name == SecName) {
194 "cannot dump section '%s': it has no contents",
195 SecName.str().c_str());
198 if (!BufferOrErr)
200 std::unique_ptr Buf = std::move(*BufferOrErr);
201 std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(),
202 Buf->getBufferStart());
203 if (Error E = Buf->commit())
204 return E;
206 }
207 }
208 return createStringError(object_error::parse_failed, "section '%s' not found",
209 SecName.str().c_str());
210}
211
213
214
215
217 ToReplace;
219 std::optional CType;
220 for (auto &[Matcher, T] : Config.compressSections)
221 if (Matcher.matches(Sec.Name))
222 CType = T;
223
224
227 CType = Config.CompressionType;
228 else if (Config.DecompressDebugSections)
230 }
231 if (!CType)
232 continue;
233
234 if (Sec.ParentSegment)
237 "section '" + Sec.Name +
238 "' within a segment cannot be (de)compressed");
239
240 if (auto *CS = dyn_cast(&Sec)) {
242 ToReplace.emplace_back(
243 &Sec, [=] { return &addSection(*CS); });
245 ToReplace.emplace_back(&Sec, [=, S = &Sec] {
246 return &addSection(
248 });
249 }
250 }
251
253 for (auto [S, Func] : ToReplace)
254 FromTo[S] = Func();
256}
257
261 return false;
263 if (.consume_front("$x") &&
.consume_front("$d"))
264 return false;
265 return Name.empty() || Name.starts_with(".");
266}
267
271 return false;
273 if (.consume_front("$a") &&
.consume_front("$d") &&
274 .consume_front("$t"))
275 return false;
276 return Name.empty() || Name.starts_with(".");
277}
278
279
283
286
288 default:
289 return false;
290 }
291}
292
297}
298
301
302
305
308 return;
309
310
311
317
321
322
323
324
325
326
327
328
329
330
331
332 if (.SymbolsToKeepGlobal.empty() &&
336
340
341
344
348
349 const auto I = Config.SymbolsToRename.find(Sym.Name);
350 if (I != Config.SymbolsToRename.end())
351 Sym.Name = std::string(I->getValue());
352
354 if (Sym.Name.compare(0, Config.SymbolsPrefixRemove.size(),
355 Config.SymbolsPrefixRemove) == 0)
357
360 });
361
362
363
364
365 if (Config.StripUnneeded || .UnneededSymbolsToRemove.empty() ||
366 .OnlySection.empty()) {
368 Sec.markSymbols();
369 }
370
371 auto RemoveSymbolsPred = [&](const Symbol &Sym) {
374 return false;
375
377 return true;
378
380 return true;
381
383 return false;
384
386 return true;
387
393 return true;
394
395 if ((Config.StripUnneeded ||
396 Config.UnneededSymbolsToRemove.matches(Sym.Name)) &&
398 return true;
399
400
403 return true;
404
405 return false;
406 };
407
409}
410
414
415
416 if (.ToRemove.empty()) {
418 return Config.ToRemove.matches(Sec.Name);
419 };
420 }
421
423 RemovePred = [RemovePred](const SectionBase &Sec) {
425 };
426
427 if (Config.ExtractDWO)
428 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
430 };
431
432 if (Config.StripAllGNU)
433 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
434 if (RemovePred(Sec))
435 return true;
436 if ((Sec.Flags & SHF_ALLOC) != 0)
437 return false;
439 return false;
440 switch (Sec.Type) {
445 return true;
446 }
448 };
449
450 if (Config.StripSections) {
451 RemovePred = [RemovePred](const SectionBase &Sec) {
452 return RemovePred(Sec) || Sec.ParentSegment == nullptr;
453 };
454 }
455
456 if (Config.StripDebug || Config.StripUnneeded) {
457 RemovePred = [RemovePred](const SectionBase &Sec) {
459 };
460 }
461
462 if (Config.StripNonAlloc)
463 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
464 if (RemovePred(Sec))
465 return true;
467 return false;
468 return (Sec.Flags & SHF_ALLOC) == 0 && Sec.ParentSegment == nullptr;
469 };
470
472 RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
473 if (RemovePred(Sec))
474 return true;
476 return false;
478 return false;
480 return false;
481
482
483
484
486 return false;
487 if (Sec.ParentSegment != nullptr)
488 return false;
489 return (Sec.Flags & SHF_ALLOC) == 0;
490 };
491
492 if (Config.ExtractPartition || Config.ExtractMainPartition) {
493 RemovePred = [RemovePred](const SectionBase &Sec) {
494 if (RemovePred(Sec))
495 return true;
497 return true;
498 return (Sec.Flags & SHF_ALLOC) != 0 && !Sec.ParentSegment;
499 };
500 }
501
502
503 if (.OnlySection.empty()) {
504 RemovePred = [&Config, RemovePred, &Obj](const SectionBase &Sec) {
505
506 if (Config.OnlySection.matches(Sec.Name))
507 return false;
508
509
510 if (RemovePred(Sec))
511 return true;
512
513
515 return false;
518 return false;
519
520
521 return true;
522 };
523 }
524
525 if (.KeepSection.empty()) {
527
528 if (Config.KeepSection.matches(Sec.Name))
529 return false;
530
531 return RemovePred(Sec);
532 };
533 }
534
535
536
537
538
539
542 RemovePred = [&Obj, RemovePred](const SectionBase &Sec) {
544 return false;
545 return RemovePred(Sec);
546 };
547 }
548
550 return E;
551
553 return E;
554
556}
557
558
560 uint8_t DefaultVisibility) {
563
566 uint8_t Visibility = DefaultVisibility;
567
569 switch (FlagValue) {
572 break;
575 break;
578 break;
581 break;
584 break;
587 break;
590 break;
593 break;
596 break;
599 break;
602 break;
603 default:
604 break;
605 };
606
610}
611
616 NewSection.SectionData->getBufferStart()),
617 NewSection.SectionData->getBufferSize());
619}
620
623
624
625
626
627
628
629
630 if (Data.empty())
632
633 if (Data.size() < 12) {
634 std::string msg;
636 << Name << " data must be either empty or at least 12 bytes long";
638 }
639 if (Data.size() % 4 != 0) {
640 std::string msg;
642 << Name << " data size must be a multiple of 4 bytes";
644 }
647
650
652 4 + 4 + 4 +
653 alignTo(NameSizeValue, 4) +
654 alignTo(DescSizeValue, 4);
656 if (ActualDataSize != ExpectedDataSize) {
657 std::string msg;
660 << " data size is incompatible with the content of "
661 "the name and description size fields:"
662 << " expecting " << ExpectedDataSize << ", found " << ActualDataSize;
664 }
665
667}
668
669
670
671
672
673
674
675
678 if (Config.OutputArch) {
681 }
682
683 if (.SplitDWO.empty() && Config.ExtractDWO) {
686 [&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); });
687 }
688
689
693 std::tie(SectionName, FileName) = Flag.split('=');
695 return E;
696 }
697
698
699
700
701
703 return E;
704
706 return E;
707
708 if (.SetSectionAlignment.empty()) {
710 auto I = Config.SetSectionAlignment.find(Sec.Name);
711 if (I != Config.SetSectionAlignment.end())
712 Sec.Align = I->second;
713 }
714 }
715
716 if (Config.ChangeSectionLMAValAll != 0) {
718 if (Seg.FileSize > 0) {
719 if (Config.ChangeSectionLMAValAll > 0 &&
720 Seg.PAddr > std::numeric_limits<uint64_t>::max() -
721 Config.ChangeSectionLMAValAll) {
725 " cannot be increased by 0x" +
727 ". The result would overflow");
728 } else if (Config.ChangeSectionLMAValAll < 0 &&
729 Seg.PAddr < std::numeric_limits<uint64_t>::min() -
730 Config.ChangeSectionLMAValAll) {
734 " cannot be decreased by 0x" +
736 ". The result would underflow");
737 }
738 Seg.PAddr += Config.ChangeSectionLMAValAll;
739 }
740 }
741 }
742
743 if (.ChangeSectionAddress.empty()) {
746 object_error::invalid_file_type,
747 "cannot change section address in a non-relocatable file");
748
752 Config.ChangeSectionAddress.rend())) {
754 if (PatternUpdate.SectionPattern.matches(Sec.Name) &&
755 SectionsToUpdateAddress.try_emplace(Sec.Name, PatternUpdate.Update)
756 .second) {
758 Sec.Addr < PatternUpdate.Update.Value) {
762 " cannot be decreased by 0x" +
764 ". The result would underflow");
765 }
767 Sec.Addr > std::numeric_limits<uint64_t>::max() -
768 PatternUpdate.Update.Value) {
772 " cannot be increased by 0x" +
774 ". The result would overflow");
775 }
776
777 switch (PatternUpdate.Update.Kind) {
779 Sec.Addr = PatternUpdate.Update.Value;
780 break;
782 Sec.Addr -= PatternUpdate.Update.Value;
783 break;
785 Sec.Addr += PatternUpdate.Update.Value;
786 break;
787 }
788 }
789 }
790 }
791 }
792
793 if (Config.OnlyKeepDebug)
794 for (auto &Sec : Obj.sections())
797
801
806 if (Name.starts_with(".note") && Name != ".note.GNU-stack") {
810 }
812 };
814 return E;
815 }
816
820 };
822 return E;
823 }
824
825 if (.AddGnuDebugLink.empty())
827 Config.GnuDebugLinkCRC32);
828
829
830
833 return E;
834
837
838
839 if (.SetSectionFlags.empty() ||
.SetSectionType.empty()) {
840 for (auto &Sec : Obj.sections()) {
841 const auto Iter = Config.SetSectionFlags.find(Sec.Name);
842 if (Iter != Config.SetSectionFlags.end()) {
845 return E;
846 }
847 auto It2 = Config.SetSectionType.find(Sec.Name);
848 if (It2 != Config.SetSectionType.end())
850 }
851 }
852
853 if (.SectionsToRename.empty()) {
854 std::vector<RelocationSectionBase *> RelocSections;
857 auto *RelocSec = dyn_cast(&Sec);
858 const auto Iter = Config.SectionsToRename.find(Sec.Name);
859 if (Iter != Config.SectionsToRename.end()) {
861 Sec.Name = std::string(SR.NewName);
864 return E;
865 }
866 RenamedSections.insert(&Sec);
867 } else if (RelocSec && !(Sec.Flags & SHF_ALLOC))
868
869
870
871
872
873
874 RelocSections.push_back(RelocSec);
875 }
876
877
879 auto Iter = RenamedSections.find(RelocSec->getSection());
880 if (Iter != RenamedSections.end())
881 RelocSec->Name = (RelocSec->getNamePrefix() + (*Iter)->Name).str();
882 }
883 }
884
885
886
887
888 if (.AllocSectionsPrefix.empty()) {
892 Sec.Name = (Config.AllocSectionsPrefix + Sec.Name).str();
893 PrefixedSections.insert(&Sec);
894 } else if (auto *RelocSec = dyn_cast(&Sec)) {
895
896
897
898
899
900
901
902 const SectionBase *TargetSec = RelocSec->getSection();
904
905
906
907
908 if (PrefixedSections.count(TargetSec))
909 Sec.Name = (RelocSec->getNamePrefix() + TargetSec->Name).str();
910 else
911 Sec.Name = (RelocSec->getNamePrefix() + Config.AllocSectionsPrefix +
912 TargetSec->Name)
913 .str();
914 }
915 }
916 }
917 }
918
922}
923
926 std::unique_ptr Writer =
929 return E;
931}
932
938 if (!Obj)
940
941 const ElfType OutputElfType =
944 return E;
946}
947
954 if (!Obj)
956
957
958
959 const ElfType OutputElfType =
962 return E;
964}
965
973 if (!Obj)
975
979
982
985
987}
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
This file defines the DenseSet and SmallDenseSet classes.
static Error replaceAndRemoveSections(const CommonConfig &Config, const ELFConfig &ELFConfig, Object &Obj)
static bool isArmMappingSymbol(const Symbol &Sym)
static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig, ElfType OutputElfType, Object &Obj)
static Error handleUserSection(const NewSectionInfo &NewSection, function_ref< Error(StringRef, ArrayRef< uint8_t >)> F)
static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo, uint8_t DefaultVisibility)
static Error updateAndRemoveSymbols(const CommonConfig &Config, const ELFConfig &ELFConfig, Object &Obj)
std::function< bool(const SectionBase &Sec)> SectionPred
static Error verifyNoteSection(StringRef Name, endianness Endianness, ArrayRef< uint8_t > Data)
static bool isDWOSection(const SectionBase &Sec)
static bool isRequiredByABISymbol(const Object &Obj, const Symbol &Sym)
static bool isDebugSection(const SectionBase &Sec)
static Error dumpSectionToFile(StringRef SecName, StringRef Filename, Object &Obj)
static Error writeOutput(const CommonConfig &Config, Object &Obj, raw_ostream &Out, ElfType OutputElfType)
static bool isUnneededSymbol(const Symbol &Sym)
static bool isAArch64MappingSymbol(const Symbol &Sym)
static bool onlyKeepDWOPred(const Object &Obj, const SectionBase &Sec)
static void setSectionType(SectionBase &Sec, uint64_t Type)
static Expected< uint64_t > getNewShfFlags(SectionFlag AllFlags, uint16_t EMachine)
static Error setSectionFlagsAndType(SectionBase &Sec, SectionFlag Flags, uint16_t EMachine)
static std::unique_ptr< Writer > createELFWriter(const CommonConfig &Config, Object &Obj, raw_ostream &Out, ElfType OutputElfType)
static uint64_t getSectionFlagsPreserveMask(uint64_t OldFlags, uint64_t NewFlags, uint16_t EMachine)
static std::unique_ptr< Writer > createWriter(const CommonConfig &Config, Object &Obj, raw_ostream &Out, ElfType OutputElfType)
static ElfType getOutputElfType(const Binary &Bin)
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Implements a dense probed hash-table based set.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
static Expected< std::unique_ptr< FileOutputBuffer > > create(StringRef FilePath, size_t Size, unsigned Flags=0)
Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...
This interface provides simple read-only access to a block of memory, and provides simple methods for...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
static Twine utohexstr(const uint64_t &Val)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find(const_arg_type_t< ValueT > V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
SectionTableRef sections() const
StringTableSection * SectionNames
bool isRelocatable() const
Error updateSection(StringRef Name, ArrayRef< uint8_t > Data)
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
T & addSection(Ts &&...Args)
Error removeSections(bool AllowBrokenLinks, std::function< bool(const SectionBase &)> ToRemove)
ConstRange< Segment > segments() const
SymbolTableSection * SymbolTable
Error compressOrDecompressSections(const CommonConfig &Config)
SectionBase * findSection(StringRef Name)
Error addNewSymbolTable()
Error replaceSections(const DenseMap< SectionBase *, SectionBase * > &FromTo)
virtual Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const =0
const SectionBase * getStrTab() const
void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility, uint16_t Shndx, uint64_t SymbolSize)
void updateSymbols(function_ref< void(Symbol &)> Callable)
virtual Error finalize()=0
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr size_t NameSize
Error executeObjcopyOnIHex(const CommonConfig &Config, const ELFConfig &ELFConfig, MemoryBuffer &In, raw_ostream &Out)
Apply the transformations described by Config and ELFConfig to In, which must represent an IHex file,...
Error executeObjcopyOnBinary(const CommonConfig &Config, const ELFConfig &ELFConfig, object::ELFObjectFileBase &In, raw_ostream &Out)
Apply the transformations described by Config and ELFConfig to In and writes the result into Out.
Error executeObjcopyOnRawBinary(const CommonConfig &Config, const ELFConfig &ELFConfig, MemoryBuffer &In, raw_ostream &Out)
Apply the transformations described by Config and ELFConfig to In, which is treated as a raw binary i...
uint32_t read32(const void *P, endianness E)
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...
std::vector< std::pair< NameMatcher, uint8_t > > SymbolsToSetVisibility
uint8_t NewSymbolVisibility
std::function< uint64_t(uint64_t)> EntryExpr
std::shared_ptr< MemoryBuffer > SectionData
std::optional< SectionFlag > NewFlags
uint16_t getShndx() const