43#include <system_error>
74 if (AllFlags & SectionFlag::SecAlloc)
76 if (!(AllFlags & SectionFlag::SecReadonly))
78 if (AllFlags & SectionFlag::SecCode)
80 if (AllFlags & SectionFlag::SecMerge)
82 if (AllFlags & SectionFlag::SecStrings)
84 if (AllFlags & SectionFlag::SecExclude)
86 if (AllFlags & SectionFlag::SecLarge) {
89 "section flag SHF_X86_64_LARGE can only be used "
90 "with x86_64 architecture");
107 return (OldFlags & PreserveMask) | (NewFlags & ~PreserveMask);
130 Flags & (SectionFlag::SecContents | SectionFlag::SecLoad)))
161 switch (OutputElfType) {
163 return std::make_unique<ELFWriter<ELF32LE>>(Obj, Out, !
Config.StripSections,
166 return std::make_unique<ELFWriter<ELF64LE>>(Obj, Out, !
Config.StripSections,
169 return std::make_unique<ELFWriter<ELF32BE>>(Obj, Out, !
Config.StripSections,
172 return std::make_unique<ELFWriter<ELF64BE>>(Obj, Out, !
Config.StripSections,
181 switch (
Config.OutputFormat) {
182 case FileFormat::Binary:
183 return std::make_unique<BinaryWriter>(Obj, Out,
Config);
184 case FileFormat::IHex:
185 return std::make_unique<IHexWriter>(Obj, Out,
Config.OutputFilename);
186 case FileFormat::SREC:
187 return std::make_unique<SRECWriter>(Obj, Out,
Config.OutputFilename);
196 if (Sec.Name == SecName) {
199 "cannot dump section '%s': it has no contents",
200 SecName.
str().c_str());
205 std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
206 std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(),
207 Buf->getBufferStart());
208 if (
Error E = Buf->commit())
214 SecName.
str().c_str());
224 std::optional<DebugCompressionType> CType;
225 for (
auto &[Matcher,
T] :
Config.compressSections)
226 if (Matcher.matches(Sec.Name))
232 CType =
Config.CompressionType;
233 else if (
Config.DecompressDebugSections)
239 if (Sec.ParentSegment)
242 "section '" + Sec.Name +
243 "' within a segment cannot be (de)compressed");
245 if (
auto *CS = dyn_cast<CompressedSection>(&Sec)) {
247 ToReplace.emplace_back(
248 &Sec, [=] {
return &addSection<DecompressedSection>(*CS); });
250 ToReplace.emplace_back(&Sec, [=, S = &Sec] {
251 return &addSection<CompressedSection>(
258 for (
auto [S, Func] : ToReplace)
268 if (!
Name.consume_front(
"$x") && !
Name.consume_front(
"$d"))
270 return Name.empty() ||
Name.starts_with(
".");
278 if (!
Name.consume_front(
"$a") && !
Name.consume_front(
"$d") &&
279 !
Name.consume_front(
"$t"))
281 return Name.empty() ||
Name.starts_with(
".");
337 if (!
Config.SymbolsToKeepGlobal.empty() &&
356 Sym.
Name = std::string(
I->getValue());
360 Config.SymbolsPrefixRemove) == 0)
370 if (
Config.StripUnneeded || !
Config.UnneededSymbolsToRemove.empty() ||
371 !
Config.OnlySection.empty()) {
376 auto RemoveSymbolsPred = [&](
const Symbol &
Sym) {
400 if ((
Config.StripUnneeded ||
421 if (!
Config.ToRemove.empty()) {
423 return Config.ToRemove.matches(Sec.Name);
428 RemovePred = [RemovePred](
const SectionBase &Sec) {
433 RemovePred = [RemovePred, &Obj](
const SectionBase &Sec) {
438 RemovePred = [RemovePred, &Obj](
const SectionBase &Sec) {
455 if (
Config.StripSections) {
456 RemovePred = [RemovePred](
const SectionBase &Sec) {
457 return RemovePred(Sec) || Sec.ParentSegment ==
nullptr;
462 RemovePred = [RemovePred](
const SectionBase &Sec) {
468 RemovePred = [RemovePred, &Obj](
const SectionBase &Sec) {
473 return (Sec.Flags &
SHF_ALLOC) == 0 && Sec.ParentSegment ==
nullptr;
477 RemovePred = [RemovePred, &Obj](
const SectionBase &Sec) {
492 if (Sec.ParentSegment !=
nullptr)
497 if (
Config.ExtractPartition ||
Config.ExtractMainPartition) {
498 RemovePred = [RemovePred](
const SectionBase &Sec) {
503 return (Sec.Flags &
SHF_ALLOC) != 0 && !Sec.ParentSegment;
508 if (!
Config.OnlySection.empty()) {
511 if (
Config.OnlySection.matches(Sec.Name))
530 if (!
Config.KeepSection.empty()) {
533 if (
Config.KeepSection.matches(Sec.Name))
536 return RemovePred(Sec);
547 RemovePred = [&Obj, RemovePred](
const SectionBase &Sec) {
550 return RemovePred(Sec);
565 uint8_t DefaultVisibility) {
571 uint8_t Visibility = DefaultVisibility;
638 if (
Data.size() < 12) {
641 <<
Name <<
" data must be either empty or at least 12 bytes long";
644 if (
Data.size() % 4 != 0) {
647 <<
Name <<
" data size must be a multiple of 4 bytes";
661 if (ActualDataSize != ExpectedDataSize) {
665 <<
" data size is incompatible with the content of "
666 "the name and description size fields:"
667 <<
" expecting " << ExpectedDataSize <<
", found " << ActualDataSize;
691 [&Obj](
const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); });
713 if (!
Config.SetSectionAlignment.empty()) {
715 auto I =
Config.SetSectionAlignment.find(Sec.Name);
716 if (
I !=
Config.SetSectionAlignment.end())
717 Sec.Align =
I->second;
721 if (
Config.ChangeSectionLMAValAll != 0) {
723 if (Seg.FileSize > 0) {
724 if (
Config.ChangeSectionLMAValAll > 0 &&
725 Seg.PAddr > std::numeric_limits<uint64_t>::max() -
726 Config.ChangeSectionLMAValAll) {
730 " cannot be increased by 0x" +
732 ". The result would overflow");
733 }
else if (
Config.ChangeSectionLMAValAll < 0 &&
734 Seg.PAddr < std::numeric_limits<uint64_t>::min() -
735 Config.ChangeSectionLMAValAll) {
739 " cannot be decreased by 0x" +
741 ". The result would underflow");
743 Seg.PAddr +=
Config.ChangeSectionLMAValAll;
748 if (!
Config.ChangeSectionAddress.empty()) {
751 object_error::invalid_file_type,
752 "cannot change section address in a non-relocatable file");
757 Config.ChangeSectionAddress.rend())) {
759 if (PatternUpdate.SectionPattern.matches(Sec.Name) &&
760 SectionsToUpdateAddress.
try_emplace(Sec.Name, PatternUpdate.Update)
763 Sec.Addr < PatternUpdate.Update.Value) {
767 " cannot be decreased by 0x" +
769 ". The result would underflow");
772 Sec.Addr > std::numeric_limits<uint64_t>::max() -
773 PatternUpdate.Update.Value) {
777 " cannot be increased by 0x" +
779 ". The result would overflow");
782 switch (PatternUpdate.Update.Kind) {
784 Sec.Addr = PatternUpdate.Update.Value;
787 Sec.Addr -= PatternUpdate.Update.Value;
790 Sec.Addr += PatternUpdate.Update.Value;
811 if (
Name.starts_with(
".note") &&
Name !=
".note.GNU-stack") {
830 if (!
Config.AddGnuDebugLink.empty())
832 Config.GnuDebugLinkCRC32);
844 if (!
Config.SetSectionFlags.empty() || !
Config.SetSectionType.empty()) {
846 const auto Iter =
Config.SetSectionFlags.find(Sec.Name);
847 if (Iter !=
Config.SetSectionFlags.end()) {
852 auto It2 =
Config.SetSectionType.find(Sec.Name);
853 if (It2 !=
Config.SetSectionType.end())
858 if (!
Config.SectionsToRename.empty()) {
859 std::vector<RelocationSectionBase *> RelocSections;
862 auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec);
863 const auto Iter =
Config.SectionsToRename.find(Sec.Name);
864 if (Iter !=
Config.SectionsToRename.end()) {
866 Sec.Name = std::string(SR.
NewName);
871 RenamedSections.
insert(&Sec);
872 }
else if (RelocSec && !(Sec.Flags &
SHF_ALLOC))
879 RelocSections.push_back(RelocSec);
884 auto Iter = RenamedSections.
find(RelocSec->getSection());
885 if (Iter != RenamedSections.
end())
886 RelocSec->Name = (RelocSec->getNamePrefix() + (*Iter)->Name).str();
893 if (!
Config.AllocSectionsPrefix.empty()) {
897 Sec.Name = (
Config.AllocSectionsPrefix + Sec.Name).str();
898 PrefixedSections.
insert(&Sec);
899 }
else if (
auto *RelocSec = dyn_cast<RelocationSectionBase>(&Sec)) {
907 const SectionBase *TargetSec = RelocSec->getSection();
913 if (PrefixedSections.
count(TargetSec))
914 Sec.
Name = (RelocSec->getNamePrefix() + TargetSec->
Name).str();
916 Sec.Name = (RelocSec->getNamePrefix() +
Config.AllocSectionsPrefix +
931 std::unique_ptr<Writer>
Writer =
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)
Provides ErrorOr<T> smart pointer.
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<X> - 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