// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "DebugMap.h"
#include "BinaryHolder.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Chrono.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cinttypes>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
namespace llvm {
+
namespace dsymutil {
using namespace llvm::object;
OS << getObjectFilename() << ":\n";
// Sort the symbols in alphabetical order, like llvm-nm (and to get
// deterministic output for testing).
- typedef std::pair<StringRef, SymbolMapping> Entry;
+ using Entry = std::pair<StringRef, SymbolMapping>;
std::vector<Entry> Entries;
Entries.reserve(Symbols.getNumItems());
for (const auto &Sym : make_range(Symbols.begin(), Symbols.end()))
#endif
namespace {
+
struct YAMLContext {
StringRef PrependPath;
Triple BinaryTriple;
};
-}
+
+} // end anonymous namespace
ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
DebugMap::parseYAMLDebugMap(StringRef InputFile, StringRef PrependPath,
Result.push_back(std::move(Res));
return std::move(Result);
}
-}
+
+} // end namespace dsymutil
namespace yaml {
io.mapRequired("symbols", Norm->Entries);
}
-void ScalarTraits<Triple>::output(const Triple &val, void *,
- llvm::raw_ostream &out) {
+void ScalarTraits<Triple>::output(const Triple &val, void *, raw_ostream &out) {
out << val.str();
}
sys::path::append(Path, Filename);
auto ErrOrObjectFiles = BinHolder.GetObjectFiles(Path);
if (auto EC = ErrOrObjectFiles.getError()) {
- llvm::errs() << "warning: Unable to open " << Path << " " << EC.message()
- << '\n';
+ errs() << "warning: Unable to open " << Path << " " << EC.message() << '\n';
} else if (auto ErrOrObjectFile = BinHolder.Get(Ctxt.BinaryTriple)) {
// Rewrite the object file symbol addresses in the debug map. The
// YAML input is mainly used to test llvm-dsymutil without
}
return Res;
}
-}
-}
+
+} // end namespace yaml
+
+} // end namespace llvm
-//=== tools/dsymutil/DebugMap.h - Generic debug map representation -*- C++ -*-//
+//=- tools/dsymutil/DebugMap.h - Generic debug map representation -*- C++ -*-=//
//
// The LLVM Linker
//
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
///
/// This file contains the class declaration of the DebugMap
/// The DebugMap is an input to the DwarfLinker class that will
/// extract the Dwarf debug information from the referenced object
/// files and link their usefull debug info together.
-///
+//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
#define LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/YAMLTraits.h"
+#include <chrono>
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
#include <vector>
namespace llvm {
+
class raw_ostream;
namespace dsymutil {
+
class DebugMapObject;
/// \brief The DebugMap object stores the list of object files to
class DebugMap {
Triple BinaryTriple;
std::string BinaryPath;
- typedef std::vector<std::unique_ptr<DebugMapObject>> ObjectContainer;
+
+ using ObjectContainer = std::vector<std::unique_ptr<DebugMapObject>>;
+
ObjectContainer Objects;
/// For YAML IO support.
///@{
friend yaml::MappingTraits<std::unique_ptr<DebugMap>>;
friend yaml::MappingTraits<DebugMap>;
+
DebugMap() = default;
///@}
+
public:
DebugMap(const Triple &BinaryTriple, StringRef BinaryPath)
: BinaryTriple(BinaryTriple), BinaryPath(BinaryPath) {}
- typedef ObjectContainer::const_iterator const_iterator;
+ using const_iterator = ObjectContainer::const_iterator;
iterator_range<const_iterator> objects() const {
return make_range(begin(), end());
Optional<yaml::Hex64> ObjectAddress;
yaml::Hex64 BinaryAddress;
yaml::Hex32 Size;
+
SymbolMapping(Optional<uint64_t> ObjectAddr, uint64_t BinaryAddress,
uint32_t Size)
: BinaryAddress(BinaryAddress), Size(Size) {
if (ObjectAddr)
ObjectAddress = *ObjectAddr;
}
+
/// For YAML IO support
SymbolMapping() = default;
};
- typedef std::pair<std::string, SymbolMapping> YAMLSymbolMapping;
- typedef StringMapEntry<SymbolMapping> DebugMapEntry;
+ using YAMLSymbolMapping = std::pair<std::string, SymbolMapping>;
+ using DebugMapEntry = StringMapEntry<SymbolMapping>;
/// \brief Adds a symbol mapping to this DebugMapObject.
/// \returns false if the symbol was already registered. The request
/// is discarded in this case.
- bool addSymbol(llvm::StringRef SymName, Optional<uint64_t> ObjectAddress,
+ bool addSymbol(StringRef SymName, Optional<uint64_t> ObjectAddress,
uint64_t LinkedAddress, uint32_t Size);
/// \brief Lookup a symbol mapping.
/// \returns null if the address isn't found.
const DebugMapEntry *lookupObjectAddress(uint64_t Address) const;
- llvm::StringRef getObjectFilename() const { return Filename; }
+ StringRef getObjectFilename() const { return Filename; }
sys::TimePoint<std::chrono::seconds> getTimestamp() const {
return Timestamp;
#ifndef NDEBUG
void dump() const;
#endif
+
private:
friend class DebugMap;
+
/// DebugMapObjects can only be constructed by the owning DebugMap.
DebugMapObject(StringRef ObjectFilename,
sys::TimePoint<std::chrono::seconds> Timestamp, uint8_t Type);
///@{
friend yaml::MappingTraits<dsymutil::DebugMapObject>;
friend yaml::SequenceTraits<std::vector<std::unique_ptr<DebugMapObject>>>;
+
DebugMapObject() = default;
public:
DebugMapObject &operator=(DebugMapObject &&) = default;
///@}
};
-}
-}
+
+} // end namespace dsymutil
+
+} // end namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::dsymutil::DebugMapObject::YAMLSymbolMapping)
};
template <> struct ScalarTraits<Triple> {
- static void output(const Triple &val, void *, llvm::raw_ostream &out);
+ static void output(const Triple &val, void *, raw_ostream &out);
static StringRef input(StringRef scalar, void *, Triple &value);
static bool mustQuote(StringRef) { return true; }
};
template <> struct MappingTraits<std::unique_ptr<dsymutil::DebugMap>> {
static void mapping(IO &io, std::unique_ptr<dsymutil::DebugMap> &DM);
};
-}
-}
+
+} // end namespace yaml
+} // end namespace llvm
#endif // LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "BinaryHolder.h"
#include "DebugMap.h"
#include "MachOUtils.h"
#include "NonRelocatableStringpool.h"
#include "dsymutil.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/BinaryFormat/MachO.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/Config/config.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFSection.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm/Object/MachO.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/LEB128.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include <algorithm>
+#include <cassert>
+#include <cinttypes>
+#include <climits>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <limits>
+#include <map>
#include <memory>
#include <string>
+#include <system_error>
#include <tuple>
+#include <utility>
+#include <vector>
namespace llvm {
namespace dsymutil {
IntervalMap<KeyT, ValT, IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
IntervalMapHalfOpenInfo<KeyT>>;
-typedef HalfOpenIntervalMap<uint64_t, int64_t> FunctionIntervals;
+using FunctionIntervals = HalfOpenIntervalMap<uint64_t, int64_t>;
// FIXME: Delete this structure.
struct PatchLocation {
/// specific DeclContext using a separate DenseMap keyed on the hash
/// of the fully qualified name of the context.
class DeclContext {
+ friend DeclMapInfo;
+
unsigned QualifiedNameHash = 0;
uint32_t Line = 0;
uint32_t ByteSize = 0;
uint32_t LastSeenCompileUnitID = 0;
uint32_t CanonicalDIEOffset = 0;
- friend DeclMapInfo;
-
public:
- typedef DenseSet<DeclContext *, DeclMapInfo> Map;
+ using Map = DenseSet<DeclContext *, DeclMapInfo>;
DeclContext() : DefinedInClangModule(0), Parent(*this) {}
public:
/// Information gathered about a DIE in the object file.
struct DIEInfo {
- int64_t AddrAdjust; ///< Address offset to apply to the described entity.
- DeclContext *Ctxt; ///< ODR Declaration context.
- DIE *Clone; ///< Cloned version of that DIE.
- uint32_t ParentIdx; ///< The index of this DIE's parent.
- bool Keep : 1; ///< Is the DIE part of the linked output?
- bool InDebugMap : 1; ///< Was this DIE's entity found in the map?
- bool Prune : 1; ///< Is this a pure forward declaration we can strip?
- bool Incomplete : 1; ///< Does DIE transitively refer an incomplete decl?
+ /// Address offset to apply to the described entity.
+ int64_t AddrAdjust;
+
+ /// ODR Declaration context.
+ DeclContext *Ctxt;
+
+ /// Cloned version of that DIE.
+ DIE *Clone;
+
+ /// The index of this DIE's parent.
+ uint32_t ParentIdx;
+
+ /// Is the DIE part of the linked output?
+ bool Keep : 1;
+
+ /// Was this DIE's entity found in the map?
+ bool InDebugMap : 1;
+
+ /// Is this a pure forward declaration we can strip?
+ bool Prune : 1;
+
+ /// Does DIE transitively refer an incomplete decl?
+ bool Incomplete : 1;
};
CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR,
StringRef ClangModuleName)
- : OrigUnit(OrigUnit), ID(ID), LowPc(UINT64_MAX), HighPc(0), RangeAlloc(),
- Ranges(RangeAlloc), ClangModuleName(ClangModuleName) {
+ : OrigUnit(OrigUnit), ID(ID), Ranges(RangeAlloc),
+ ClangModuleName(ClangModuleName) {
Info.resize(OrigUnit.getNumDIEs());
auto CUDie = OrigUnit.getUnitDIE(false);
Optional<PatchLocation> getUnitRangesAttribute() const {
return UnitRangeAttribute;
}
+
const FunctionIntervals &getFunctionRanges() const { return Ranges; }
+
const std::vector<PatchLocation> &getRangesAttributes() const {
return RangeAttributes;
}
uint64_t StartOffset;
uint64_t NextUnitOffset;
- uint64_t LowPc;
- uint64_t HighPc;
+ uint64_t LowPc = std::numeric_limits<uint64_t>::max();
+ uint64_t HighPc = 0;
/// A list of attributes to fixup with the absolute offset of
/// a DIE in the debug_info section.
PatchLocation>> ForwardDIEReferences;
FunctionIntervals::Allocator RangeAlloc;
+
/// The ranges in that interval map are the PC ranges for
/// functions in this unit, associated with the PC offset to apply
/// to the addresses to get the linked address.
/// Is this unit subject to the ODR rule?
bool HasODR;
+
/// Did a DIE actually contain a valid reloc?
bool HasInterestingContent;
+
/// If this is a Clang module, this holds the module's name.
std::string ClangModuleName;
};
+} // end anonymous namespace
+
void CompileUnit::markEverythingAsKept() {
for (auto &I : Info)
// Mark everything that wasn't explicity marked for pruning.
Pubtypes.emplace_back(Name, Die, Offset, false);
}
+namespace {
+
/// The Dwarf streaming logic
///
/// All interactions with the MC layer that is used to build the debug
uint32_t getFrameSectionSize() const { return FrameSectionSize; }
};
+} // end anonymous namespace
+
bool DwarfStreamer::init(Triple TheTriple, StringRef OutputFilename) {
std::string ErrorStr;
std::string TripleName;
if (Rows.empty()) {
// We only have the dummy entry, dsymutil emits an entry with a 0
// address in that case.
- MCDwarfLineAddr::Encode(*MC, Params, INT64_MAX, 0, EncodingOS);
+ MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
+ EncodingOS);
MS->EmitBytes(EncodingOS.str());
LineSectionSize += EncodingBuffer.size();
MS->EmitLabel(LineEndSym);
MS->EmitULEB128IntValue(AddressDelta);
LineSectionSize += 1 + getULEB128Size(AddressDelta);
}
- MCDwarfLineAddr::Encode(*MC, Params, INT64_MAX, 0, EncodingOS);
+ MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(),
+ 0, EncodingOS);
MS->EmitBytes(EncodingOS.str());
LineSectionSize += EncodingBuffer.size();
EncodingBuffer.resize(0);
}
if (RowsSinceLastSequence) {
- MCDwarfLineAddr::Encode(*MC, Params, INT64_MAX, 0, EncodingOS);
+ MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0,
+ EncodingOS);
MS->EmitBytes(EncodingOS.str());
LineSectionSize += EncodingBuffer.size();
EncodingBuffer.resize(0);
FrameSectionSize += FDEBytes.size() + 8 + AddrSize;
}
+namespace {
+
/// The core of the Dwarf linking logic.
///
/// The link of the dwarf information from the object files will be
/// ValidRelocs is sorted by file offset, keeping this index
/// uptodate is all we have to do to have a cheap lookup during the
/// root DIE selection and during DIE cloning.
- unsigned NextValidReloc;
+ unsigned NextValidReloc = 0;
public:
- RelocationManager(DwarfLinker &Linker)
- : Linker(Linker), NextValidReloc(0) {}
+ RelocationManager(DwarfLinker &Linker) : Linker(Linker) {}
bool hasValidRelocs() const { return !ValidRelocs.empty(); }
+
/// Reset the NextValidReloc counter.
void resetValidRelocs() { NextValidReloc = 0; }
class DIECloner {
DwarfLinker &Linker;
RelocationManager &RelocMgr;
+
/// Allocator used for all the DIEValue objects.
BumpPtrAllocator &DIEAlloc;
+
std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
LinkOptions Options;
void cloneAllCompileUnits(DWARFContext &DwarfContext);
private:
- typedef DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec;
+ using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
/// Information gathered and exchanged between the various
/// clone*Attributes helpers about the attributes of a particular DIE.
struct AttributesInfo {
- const char *Name, *MangledName; ///< Names.
- uint32_t NameOffset, MangledNameOffset; ///< Offsets in the string pool.
+ /// Names.
+ const char *Name = nullptr;
+ const char *MangledName = nullptr;
+
+ /// Offsets in the string pool.
+ uint32_t NameOffset = 0;
+ uint32_t MangledNameOffset = 0;
+
+ /// Value of AT_low_pc in the input DIE
+ uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max();
- uint64_t OrigLowPc; ///< Value of AT_low_pc in the input DIE
- uint64_t OrigHighPc; ///< Value of AT_high_pc in the input DIE
- int64_t PCOffset; ///< Offset to apply to PC addresses inside a function.
+ /// Value of AT_high_pc in the input DIE
+ uint64_t OrigHighPc = 0;
- bool HasLowPc; ///< Does the DIE have a low_pc attribute?
- bool IsDeclaration; ///< Is this DIE only a declaration?
+ /// Offset to apply to PC addresses inside a function.
+ int64_t PCOffset = 0;
- AttributesInfo()
- : Name(nullptr), MangledName(nullptr), NameOffset(0),
- MangledNameOffset(0), OrigLowPc(UINT64_MAX), OrigHighPc(0),
- PCOffset(0), HasLowPc(false), IsDeclaration(false) {}
+ /// Does the DIE have a low_pc attribute?
+ bool HasLowPc = false;
+
+ /// Is this DIE only a declaration?
+ bool IsDeclaration = false;
+
+ AttributesInfo() = default;
};
/// Helper for cloneDIE.
/// Assign an abbreviation number to \p Abbrev
void AssignAbbrev(DIEAbbrev &Abbrev);
- /// FoldingSet that uniques the abbreviations.
- FoldingSet<DIEAbbrev> AbbreviationsSet;
- /// Storage for the unique Abbreviations.
- /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot
- /// be changed to a vecot of unique_ptrs.
- std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
-
/// Compute and emit debug_ranges section for \p Unit, and
/// patch the attributes referencing it.
void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf) const;
void patchFrameInfoForObject(const DebugMapObject &, DWARFContext &,
unsigned AddressSize);
+ /// FoldingSet that uniques the abbreviations.
+ FoldingSet<DIEAbbrev> AbbreviationsSet;
+
+ /// Storage for the unique Abbreviations.
+ /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot
+ /// be changed to a vecot of unique_ptrs.
+ std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
+
/// DIELoc objects that need to be destructed (but not freed!).
std::vector<DIELoc *> DIELocs;
+
/// DIEBlock objects that need to be destructed (but not freed!).
std::vector<DIEBlock *> DIEBlocks;
+
/// Allocator used for all the DIEValue objects.
BumpPtrAllocator DIEAlloc;
/// @}
BinaryHolder BinHolder;
std::unique_ptr<DwarfStreamer> Streamer;
uint64_t OutputDebugInfoSize;
- unsigned UnitID; ///< A unique ID that identifies each compile unit.
+
+ /// A unique ID that identifies each compile unit.
+ unsigned UnitID;
+
unsigned MaxDwarfVersion = 0;
/// The units of the current debug map object.
std::vector<std::unique_ptr<CompileUnit>> Units;
-
/// The debug map object currently under consideration.
DebugMapObject *CurrentDebugObject;
bool ArchiveHintDisplayed = false;
};
+} // end anonymous namespace
+
/// Similar to DWARFUnitSection::getUnitForOffset(), but returning our
/// CompileUnit object instead.
static CompileUnit *getUnitForOffset(
return PointerIntPair<DeclContext *, 1>(nullptr);
unsigned Line = 0;
- unsigned ByteSize = UINT32_MAX;
+ unsigned ByteSize = std::numeric_limits<uint32_t>::max();
if (!InClangModule) {
// Gather some discriminating data about the DeclContext we will be
// namespaces, use these additional data points to make the process
// safer. This is disabled for clang modules, because forward
// declarations of module-defined types do not have a file and line.
- ByteSize = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_byte_size), UINT64_MAX);
+ ByteSize = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_byte_size),
+ std::numeric_limits<uint64_t>::max());
if (Tag != dwarf::DW_TAG_namespace || !Name) {
if (unsigned FileNum = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_decl_file), 0)) {
if (const auto *LT = U.getOrigUnit().getContext().getLineTableForUnit(
const auto &ValidReloc = ValidRelocs[NextValidReloc++];
const auto &Mapping = ValidReloc.Mapping->getValue();
- uint64_t ObjectAddress =
- Mapping.ObjectAddress ? uint64_t(*Mapping.ObjectAddress) : UINT64_MAX;
+ uint64_t ObjectAddress = Mapping.ObjectAddress
+ ? uint64_t(*Mapping.ObjectAddress)
+ : std::numeric_limits<uint64_t>::max();
if (Linker.Options.Verbose)
outs() << "Found valid debug map entry: " << ValidReloc.Mapping->getKey()
<< " " << format("\t%016" PRIx64 " => %016" PRIx64, ObjectAddress,
// relocated because it happens to match the low_pc of the
// enclosing subprogram. To prevent issues with that, always use
// the low_pc from the input DIE if relocations have been applied.
- Addr = (Info.OrigLowPc != UINT64_MAX ? Info.OrigLowPc : Addr) +
+ Addr = (Info.OrigLowPc != std::numeric_limits<uint64_t>::max()
+ ? Info.OrigLowPc
+ : Addr) +
Info.PCOffset;
else if (Die.getTag() == dwarf::DW_TAG_compile_unit) {
Addr = Unit.getLowPc();
- if (Addr == UINT64_MAX)
+ if (Addr == std::numeric_limits<uint64_t>::max())
return 0;
}
Info.HasLowPc = true;
// Also store the low_pc. It might get relocated in an
// inline_subprogram that happens at the beginning of its
// inlining function.
- AttrInfo.OrigLowPc =
- dwarf::toAddress(InputDIE.find(dwarf::DW_AT_low_pc), UINT64_MAX);
+ AttrInfo.OrigLowPc = dwarf::toAddress(InputDIE.find(dwarf::DW_AT_low_pc),
+ std::numeric_limits<uint64_t>::max());
}
// Reset the Offset to 0 as we will be working on the local copy of
}
bool DwarfLinker::link(const DebugMap &Map) {
-
if (!createStreamer(Map.getTriple(), OutputFilename))
return false;
return Options.NoOutput ? true : Streamer->finish(Map);
}
-}
/// Get the offset of string \p S in the string table. This
/// can insert a new element or return the offset of a preexisitng
DwarfLinker Linker(OutputFilename, Options);
return Linker.link(DM);
}
-}
-}
+
+} // end namespace dsymutil
+} // end namespace llvm
-//===-- NonRelocatableStringpool.h - A simple stringpool -----------------===//
+//===- NonRelocatableStringpool.h - A simple stringpool --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_TOOLS_DSYMUTIL_NONRELOCATABLESTRINGPOOL_H
#define LLVM_TOOLS_DSYMUTIL_NONRELOCATABLESTRINGPOOL_H
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include <cstdint>
+#include <utility>
namespace llvm {
namespace dsymutil {
/// \brief Entries are stored into the StringMap and simply linked
/// together through the second element of this pair in order to
/// keep track of insertion order.
- typedef StringMap<std::pair<uint32_t, StringMapEntryBase *>, BumpPtrAllocator>
- MapTy;
+ using MapTy =
+ StringMap<std::pair<uint32_t, StringMapEntryBase *>, BumpPtrAllocator>;
- NonRelocatableStringpool()
- : CurrentEndOffset(0), Sentinel(0), Last(&Sentinel) {
+ NonRelocatableStringpool() : Sentinel(0), Last(&Sentinel) {
// Legacy dsymutil puts an empty string at the start of the line
// table.
getStringOffset("");
private:
MapTy Strings;
- uint32_t CurrentEndOffset;
+ uint32_t CurrentEndOffset = 0;
MapTy::MapEntryTy Sentinel, *Last;
};
-}
-}
-#endif
+} // end namespace dsymutil
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_DSYMUTIL_NONRELOCATABLESTRINGPOOL_H
-//===-- dsymutil.cpp - Debug info dumping utility for llvm ----------------===//
+//===- dsymutil.cpp - Debug info dumping utility for llvm -----------------===//
//
// The LLVM Compiler Infrastructure
//
#include "dsymutil.h"
#include "DebugMap.h"
#include "MachOUtils.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Object/MachO.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Options.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/thread.h"
+#include <algorithm>
#include <cstdint>
+#include <cstdlib>
#include <string>
+#include <system_error>
-using namespace llvm::dsymutil;
-
-namespace {
using namespace llvm::cl;
+using namespace llvm::dsymutil;
-OptionCategory DsymCategory("Specific Options");
+static OptionCategory DsymCategory("Specific Options");
static opt<bool> Help("h", desc("Alias for -help"), Hidden);
static opt<bool> Version("v", desc("Alias for -version"), Hidden);
NoOutput("no-output",
desc("Do the link in memory, but do not emit the result file."),
init(false), cat(DsymCategory));
+
static opt<bool>
NoTimestamp("no-swiftmodule-timestamp",
desc("Don't check timestamp for swiftmodule files."),
init(false), cat(DsymCategory));
+
static list<std::string> ArchFlags(
"arch",
desc("Link DWARF debug information only for specified CPU architecture\n"
static opt<bool> InputIsYAMLDebugMap(
"y", desc("Treat the input file is a YAML debug map rather than a binary."),
init(false), cat(DsymCategory));
-}
static bool createPlistFile(llvm::StringRef BundleRoot) {
if (NoOutput)
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
///
/// This file contains the class declaration for the code that parses STABS
/// debug maps that are embedded in the binaries symbol tables.
-///
+//
//===----------------------------------------------------------------------===//
+
#ifndef LLVM_TOOLS_DSYMUTIL_DSYMUTIL_H
#define LLVM_TOOLS_DSYMUTIL_DSYMUTIL_H
#include "DebugMap.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorOr.h"
#include <memory>
+#include <string>
+#include <vector>
namespace llvm {
namespace dsymutil {
struct LinkOptions {
- bool Verbose; ///< Verbosity
- bool NoOutput; ///< Skip emitting output
- bool NoODR; ///< Do not unique types according to ODR
- bool NoTimestamp; ///< Do not check swiftmodule timestamp
- std::string PrependPath; ///< -oso-prepend-path
+ /// Verbosity
+ bool Verbose = false;
+
+ /// Skip emitting output
+ bool NoOutput = false;
- LinkOptions() : Verbose(false), NoOutput(false), NoTimestamp(false) {}
+ /// Do not unique types according to ODR
+ bool NoODR;
+
+ /// Do not check swiftmodule timestamp
+ bool NoTimestamp = false;
+
+ /// -oso-prepend-path
+ std::string PrependPath;
+
+ LinkOptions() = default;
};
/// \brief Extract the DebugMaps from the given file.
/// The file has to be a MachO object file. Multiple debug maps can be
/// returned when the file is universal (aka fat) binary.
-llvm::ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
+ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
parseDebugMap(StringRef InputFile, ArrayRef<std::string> Archs,
StringRef PrependPath, bool Verbose, bool InputIsYAML);
void warn(const Twine &Warning, const Twine &Context);
bool error(const Twine &Error, const Twine &Context);
-}
-}
+
+} // end namespace dsymutil
+} // end namespace llvm
+
#endif // LLVM_TOOLS_DSYMUTIL_DSYMUTIL_H
-//===- Object.cpp -----------------------------------------------*- C++ -*-===//
+//===- Object.cpp ---------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "Object.h"
#include "llvm-objcopy.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileOutputBuffer.h"
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <utility>
+#include <vector>
using namespace llvm;
using namespace object;
using namespace ELF;
template <class ELFT> void Segment::writeHeader(FileOutputBuffer &Out) const {
- typedef typename ELFT::Ehdr Elf_Ehdr;
- typedef typename ELFT::Phdr Elf_Phdr;
+ using Elf_Ehdr = typename ELFT::Ehdr;
+ using Elf_Phdr = typename ELFT::Phdr;
uint8_t *Buf = Out.getBufferStart();
Buf += sizeof(Elf_Ehdr) + Index * sizeof(Elf_Phdr);
}
template <class ELFT>
-void SymbolTableSectionImpl<ELFT>::writeSection(
- llvm::FileOutputBuffer &Out) const {
+void SymbolTableSectionImpl<ELFT>::writeSection(FileOutputBuffer &Out) const {
uint8_t *Buf = Out.getBufferStart();
Buf += Offset;
typename ELFT::Sym *Sym = reinterpret_cast<typename ELFT::Sym *>(Buf);
void RelocSectionWithSymtabBase<SymTabType>::removeSectionReferences(
const SectionBase *Sec) {
if (Symbols == Sec) {
- error("Symbol table " + Symbols->Name + " cannot be removed because it is "
- "referenced by the relocation "
- "section " +
+ error("Symbol table " + Symbols->Name +
+ " cannot be removed because it is "
+ "referenced by the relocation "
+ "section " +
this->Name);
}
}
" is not a symbol table"));
if (Info != SHN_UNDEF)
- setSection(SecTable.getSection(Info,
- "Info field value " + Twine(Info) +
- " in section " + Name + " is invalid"));
+ setSection(SecTable.getSection(Info, "Info field value " + Twine(Info) +
+ " in section " + Name +
+ " is invalid"));
else
setSection(nullptr);
}
}
template <class ELFT>
-void RelocationSection<ELFT>::writeSection(llvm::FileOutputBuffer &Out) const {
+void RelocationSection<ELFT>::writeSection(FileOutputBuffer &Out) const {
uint8_t *Buf = Out.getBufferStart() + Offset;
if (Type == SHT_REL)
writeRel(reinterpret_cast<Elf_Rel *>(Buf));
writeRel(reinterpret_cast<Elf_Rela *>(Buf));
}
-void DynamicRelocationSection::writeSection(llvm::FileOutputBuffer &Out) const {
+void DynamicRelocationSection::writeSection(FileOutputBuffer &Out) const {
std::copy(std::begin(Contents), std::end(Contents),
Out.getBufferStart() + Offset);
}
void SectionWithStrTab::removeSectionReferences(const SectionBase *Sec) {
if (StrTab == Sec) {
- error("String table " + StrTab->Name + " cannot be removed because it is "
- "referenced by the section " +
+ error("String table " + StrTab->Name +
+ " cannot be removed because it is "
+ "referenced by the section " +
this->Name);
}
}
}
void SectionWithStrTab::initialize(SectionTableRef SecTable) {
- auto StrTab = SecTable.getSection(Link,
- "Link field value " + Twine(Link) +
- " in section " + Name + " is invalid");
+ auto StrTab =
+ SecTable.getSection(Link, "Link field value " + Twine(Link) +
+ " in section " + Name + " is invalid");
if (StrTab->Type != SHT_STRTAB) {
error("Link field value " + Twine(Link) + " in section " + Name +
" is not a string table");
}
template <class ELFT>
-void Object<ELFT>::initSymbolTable(const llvm::object::ELFFile<ELFT> &ElfFile,
+void Object<ELFT>::initSymbolTable(const object::ELFFile<ELFT> &ElfFile,
SymbolTableSection *SymTab,
SectionTableRef SecTable) {
-
const Elf_Shdr &Shdr = *unwrapOrError(ElfFile.getSection(SymTab->Index));
StringRef StrTabData = unwrapOrError(ElfFile.getStringTableForSymtab(Shdr));
}
} else if (Sym.st_shndx != SHN_UNDEF) {
DefSection = SecTable.getSection(
- Sym.st_shndx,
- "Symbol '" + Name + "' is defined in invalid section with index " +
- Twine(Sym.st_shndx));
+ Sym.st_shndx, "Symbol '" + Name +
+ "' is defined in invalid section with index " +
+ Twine(Sym.st_shndx));
}
SymTab->addSymbol(Name, Sym.getBinding(), Sym.getType(), DefSection,
template <class T>
T *SectionTableRef::getSectionOfType(uint16_t Index, Twine IndexErrMsg,
Twine TypeErrMsg) {
- if (T *Sec = llvm::dyn_cast<T>(getSection(Index, IndexErrMsg)))
+ if (T *Sec = dyn_cast<T>(getSection(Index, IndexErrMsg)))
return Sec;
error(TypeErrMsg);
}
template <class ELFT>
std::unique_ptr<SectionBase>
-Object<ELFT>::makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,
+Object<ELFT>::makeSection(const object::ELFFile<ELFT> &ElfFile,
const Elf_Shdr &Shdr) {
ArrayRef<uint8_t> Data;
switch (Shdr.sh_type) {
template <class ELFT>
void Object<ELFT>::writeSectionData(FileOutputBuffer &Out) const {
for (auto &Section : Sections)
- Section->writeSection(Out);
+ Section->writeSection(Out);
}
template <class ELFT>
for (auto &Segment : this->Segments) {
// GNU objcopy does not output segments that do not cover a section. Such
// segments can sometimes be produced by LLD due to how LLD handles PT_PHDR.
- if (Segment->Type == llvm::ELF::PT_LOAD &&
- Segment->firstSection() != nullptr) {
+ if (Segment->Type == PT_LOAD && Segment->firstSection() != nullptr) {
Segment->writeSegment(Out);
}
}
}
template <class ELFT> void BinaryObject<ELFT>::finalize() {
-
// Put all segments in offset order.
auto CompareSegments = [](const SegPtr &A, const SegPtr &B) {
return A->Offset < B->Offset;
uint64_t Offset = 0;
for (auto &Segment : this->Segments) {
- if (Segment->Type == llvm::ELF::PT_LOAD &&
- Segment->firstSection() != nullptr) {
+ if (Segment->Type == PT_LOAD && Segment->firstSection() != nullptr) {
Offset = alignTo(Offset, Segment->Align);
Segment->Offset = Offset;
Offset += Segment->FileSize;
TotalSize = Offset;
}
+namespace llvm {
+
template class Object<ELF64LE>;
template class Object<ELF64BE>;
template class Object<ELF32LE>;
template class BinaryObject<ELF64BE>;
template class BinaryObject<ELF32LE>;
template class BinaryObject<ELF32BE>;
+
+} // end namespace llvm
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_OBJCOPY_OBJECT_H
-#define LLVM_OBJCOPY_OBJECT_H
+#ifndef LLVM_TOOLS_OBJCOPY_OBJECT_H
+#define LLVM_TOOLS_OBJCOPY_OBJECT_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Object/ELFObjectFile.h"
-#include "llvm/Support/FileOutputBuffer.h"
-
+#include <cstddef>
+#include <cstdint>
+#include <functional>
#include <memory>
#include <set>
+#include <vector>
-class Segment;
+namespace llvm {
+
+class FileOutputBuffer;
class SectionBase;
+class Segment;
class SectionTableRef {
private:
- llvm::ArrayRef<std::unique_ptr<SectionBase>> Sections;
+ ArrayRef<std::unique_ptr<SectionBase>> Sections;
public:
- SectionTableRef(llvm::ArrayRef<std::unique_ptr<SectionBase>> Secs)
+ SectionTableRef(ArrayRef<std::unique_ptr<SectionBase>> Secs)
: Sections(Secs) {}
SectionTableRef(const SectionTableRef &) = default;
- SectionBase *getSection(uint16_t Index, llvm::Twine ErrMsg);
+ SectionBase *getSection(uint16_t Index, Twine ErrMsg);
template <class T>
- T *getSectionOfType(uint16_t Index, llvm::Twine IndexErrMsg,
- llvm::Twine TypeErrMsg);
+ T *getSectionOfType(uint16_t Index, Twine IndexErrMsg, Twine TypeErrMsg);
};
class SectionBase {
public:
- llvm::StringRef Name;
+ StringRef Name;
Segment *ParentSegment = nullptr;
uint64_t HeaderOffset;
uint64_t OriginalOffset;
uint32_t EntrySize = 0;
uint64_t Flags = 0;
uint64_t Info = 0;
- uint64_t Link = llvm::ELF::SHN_UNDEF;
+ uint64_t Link = ELF::SHN_UNDEF;
uint64_t NameIndex = 0;
uint64_t Offset = 0;
uint64_t Size = 0;
- uint64_t Type = llvm::ELF::SHT_NULL;
+ uint64_t Type = ELF::SHT_NULL;
+
+ virtual ~SectionBase() = default;
- virtual ~SectionBase() {}
virtual void initialize(SectionTableRef SecTable);
virtual void finalize();
virtual void removeSectionReferences(const SectionBase *Sec);
- template <class ELFT> void writeHeader(llvm::FileOutputBuffer &Out) const;
- virtual void writeSection(llvm::FileOutputBuffer &Out) const = 0;
+ template <class ELFT> void writeHeader(FileOutputBuffer &Out) const;
+ virtual void writeSection(FileOutputBuffer &Out) const = 0;
};
class Segment {
};
std::set<const SectionBase *, SectionCompare> Sections;
- llvm::ArrayRef<uint8_t> Contents;
+ ArrayRef<uint8_t> Contents;
public:
uint64_t Align;
uint64_t OriginalOffset;
Segment *ParentSegment = nullptr;
- Segment(llvm::ArrayRef<uint8_t> Data) : Contents(Data) {}
+ Segment(ArrayRef<uint8_t> Data) : Contents(Data) {}
+
const SectionBase *firstSection() const {
if (!Sections.empty())
return *Sections.begin();
return nullptr;
}
+
void removeSection(const SectionBase *Sec) { Sections.erase(Sec); }
void addSection(const SectionBase *Sec) { Sections.insert(Sec); }
- template <class ELFT> void writeHeader(llvm::FileOutputBuffer &Out) const;
- void writeSegment(llvm::FileOutputBuffer &Out) const;
+ template <class ELFT> void writeHeader(FileOutputBuffer &Out) const;
+ void writeSegment(FileOutputBuffer &Out) const;
};
class Section : public SectionBase {
private:
- llvm::ArrayRef<uint8_t> Contents;
+ ArrayRef<uint8_t> Contents;
public:
- Section(llvm::ArrayRef<uint8_t> Data) : Contents(Data) {}
- void writeSection(llvm::FileOutputBuffer &Out) const override;
+ Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
+
+ void writeSection(FileOutputBuffer &Out) const override;
};
// There are two types of string tables that can exist, dynamic and not dynamic.
// then agrees with the makeSection method used to construct most sections.
class StringTableSection : public SectionBase {
private:
- llvm::StringTableBuilder StrTabBuilder;
+ StringTableBuilder StrTabBuilder;
public:
- StringTableSection() : StrTabBuilder(llvm::StringTableBuilder::ELF) {
- Type = llvm::ELF::SHT_STRTAB;
+ StringTableSection() : StrTabBuilder(StringTableBuilder::ELF) {
+ Type = ELF::SHT_STRTAB;
}
- void addString(llvm::StringRef Name);
- uint32_t findIndex(llvm::StringRef Name) const;
+ void addString(StringRef Name);
+ uint32_t findIndex(StringRef Name) const;
void finalize() override;
- void writeSection(llvm::FileOutputBuffer &Out) const override;
+ void writeSection(FileOutputBuffer &Out) const override;
+
static bool classof(const SectionBase *S) {
- if (S->Flags & llvm::ELF::SHF_ALLOC)
+ if (S->Flags & ELF::SHF_ALLOC)
return false;
- return S->Type == llvm::ELF::SHT_STRTAB;
+ return S->Type == ELF::SHT_STRTAB;
}
};
// SYMBOL_SIMPLE_INDEX means that the st_shndx is just an index of a section.
enum SymbolShndxType {
SYMBOL_SIMPLE_INDEX = 0,
- SYMBOL_ABS = llvm::ELF::SHN_ABS,
- SYMBOL_COMMON = llvm::ELF::SHN_COMMON,
- SYMBOL_HEXAGON_SCOMMON = llvm::ELF::SHN_HEXAGON_SCOMMON,
- SYMBOL_HEXAGON_SCOMMON_2 = llvm::ELF::SHN_HEXAGON_SCOMMON_2,
- SYMBOL_HEXAGON_SCOMMON_4 = llvm::ELF::SHN_HEXAGON_SCOMMON_4,
- SYMBOL_HEXAGON_SCOMMON_8 = llvm::ELF::SHN_HEXAGON_SCOMMON_8,
+ SYMBOL_ABS = ELF::SHN_ABS,
+ SYMBOL_COMMON = ELF::SHN_COMMON,
+ SYMBOL_HEXAGON_SCOMMON = ELF::SHN_HEXAGON_SCOMMON,
+ SYMBOL_HEXAGON_SCOMMON_2 = ELF::SHN_HEXAGON_SCOMMON_2,
+ SYMBOL_HEXAGON_SCOMMON_4 = ELF::SHN_HEXAGON_SCOMMON_4,
+ SYMBOL_HEXAGON_SCOMMON_8 = ELF::SHN_HEXAGON_SCOMMON_8,
};
struct Symbol {
SectionBase *DefinedIn = nullptr;
SymbolShndxType ShndxType;
uint32_t Index;
- llvm::StringRef Name;
+ StringRef Name;
uint32_t NameIndex;
uint64_t Size;
uint8_t Type;
std::vector<std::unique_ptr<Symbol>> Symbols;
StringTableSection *SymbolNames = nullptr;
- typedef std::unique_ptr<Symbol> SymPtr;
+ using SymPtr = std::unique_ptr<Symbol>;
public:
void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; }
- void addSymbol(llvm::StringRef Name, uint8_t Bind, uint8_t Type,
+ void addSymbol(StringRef Name, uint8_t Bind, uint8_t Type,
SectionBase *DefinedIn, uint64_t Value, uint16_t Shndx,
uint64_t Sz);
void addSymbolNames();
void removeSectionReferences(const SectionBase *Sec) override;
void initialize(SectionTableRef SecTable) override;
void finalize() override;
+
static bool classof(const SectionBase *S) {
- return S->Type == llvm::ELF::SHT_SYMTAB;
+ return S->Type == ELF::SHT_SYMTAB;
}
};
// Only writeSection depends on the ELF type so we implement it in a subclass.
template <class ELFT> class SymbolTableSectionImpl : public SymbolTableSection {
- void writeSection(llvm::FileOutputBuffer &Out) const override;
+ void writeSection(FileOutputBuffer &Out) const override;
};
struct Relocation {
void setSection(SectionBase *Sec) { SecToApplyRel = Sec; }
static bool classof(const SectionBase *S) {
- return S->Type == llvm::ELF::SHT_REL || S->Type == llvm::ELF::SHT_RELA;
+ return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA;
}
};
SymTabType *Symbols = nullptr;
protected:
- RelocSectionWithSymtabBase() {}
+ RelocSectionWithSymtabBase() = default;
public:
void setSymTab(SymTabType *StrTab) { Symbols = StrTab; }
-
void removeSectionReferences(const SectionBase *Sec) override;
void initialize(SectionTableRef SecTable) override;
void finalize() override;
class RelocationSection
: public RelocSectionWithSymtabBase<SymbolTableSection> {
private:
- typedef typename ELFT::Rel Elf_Rel;
- typedef typename ELFT::Rela Elf_Rela;
+ using Elf_Rel = typename ELFT::Rel;
+ using Elf_Rela = typename ELFT::Rela;
std::vector<Relocation> Relocations;
public:
void addRelocation(Relocation Rel) { Relocations.push_back(Rel); }
- void writeSection(llvm::FileOutputBuffer &Out) const override;
+ void writeSection(FileOutputBuffer &Out) const override;
static bool classof(const SectionBase *S) {
- if (S->Flags & llvm::ELF::SHF_ALLOC)
+ if (S->Flags & ELF::SHF_ALLOC)
return false;
- return S->Type == llvm::ELF::SHT_REL || S->Type == llvm::ELF::SHT_RELA;
+ return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA;
}
};
const SectionBase *StrTab = nullptr;
public:
- SectionWithStrTab(llvm::ArrayRef<uint8_t> Data) : Section(Data) {}
+ SectionWithStrTab(ArrayRef<uint8_t> Data) : Section(Data) {}
+
void setStrTab(const SectionBase *StringTable) { StrTab = StringTable; }
void removeSectionReferences(const SectionBase *Sec) override;
void initialize(SectionTableRef SecTable) override;
class DynamicSymbolTableSection : public SectionWithStrTab {
public:
- DynamicSymbolTableSection(llvm::ArrayRef<uint8_t> Data)
- : SectionWithStrTab(Data) {}
+ DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
+
static bool classof(const SectionBase *S) {
- return S->Type == llvm::ELF::SHT_DYNSYM;
+ return S->Type == ELF::SHT_DYNSYM;
}
};
class DynamicSection : public SectionWithStrTab {
public:
- DynamicSection(llvm::ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
+ DynamicSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {}
+
static bool classof(const SectionBase *S) {
- return S->Type == llvm::ELF::SHT_DYNAMIC;
+ return S->Type == ELF::SHT_DYNAMIC;
}
};
class DynamicRelocationSection
: public RelocSectionWithSymtabBase<DynamicSymbolTableSection> {
private:
- llvm::ArrayRef<uint8_t> Contents;
+ ArrayRef<uint8_t> Contents;
public:
- DynamicRelocationSection(llvm::ArrayRef<uint8_t> Data) : Contents(Data) {}
- void writeSection(llvm::FileOutputBuffer &Out) const override;
+ DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
+
+ void writeSection(FileOutputBuffer &Out) const override;
+
static bool classof(const SectionBase *S) {
- if (!(S->Flags & llvm::ELF::SHF_ALLOC))
+ if (!(S->Flags & ELF::SHF_ALLOC))
return false;
- return S->Type == llvm::ELF::SHT_REL || S->Type == llvm::ELF::SHT_RELA;
+ return S->Type == ELF::SHT_REL || S->Type == ELF::SHT_RELA;
}
};
template <class ELFT> class Object {
private:
- typedef std::unique_ptr<SectionBase> SecPtr;
- typedef std::unique_ptr<Segment> SegPtr;
+ using SecPtr = std::unique_ptr<SectionBase>;
+ using SegPtr = std::unique_ptr<Segment>;
- typedef typename ELFT::Shdr Elf_Shdr;
- typedef typename ELFT::Ehdr Elf_Ehdr;
- typedef typename ELFT::Phdr Elf_Phdr;
+ using Elf_Shdr = typename ELFT::Shdr;
+ using Elf_Ehdr = typename ELFT::Ehdr;
+ using Elf_Phdr = typename ELFT::Phdr;
- void initSymbolTable(const llvm::object::ELFFile<ELFT> &ElfFile,
+ void initSymbolTable(const object::ELFFile<ELFT> &ElfFile,
SymbolTableSection *SymTab, SectionTableRef SecTable);
- SecPtr makeSection(const llvm::object::ELFFile<ELFT> &ElfFile,
+ SecPtr makeSection(const object::ELFFile<ELFT> &ElfFile,
const Elf_Shdr &Shdr);
- void readProgramHeaders(const llvm::object::ELFFile<ELFT> &ElfFile);
- SectionTableRef readSectionHeaders(const llvm::object::ELFFile<ELFT> &ElfFile);
+ void readProgramHeaders(const object::ELFFile<ELFT> &ElfFile);
+ SectionTableRef readSectionHeaders(const object::ELFFile<ELFT> &ElfFile);
protected:
StringTableSection *SectionNames = nullptr;
std::vector<SecPtr> Sections;
std::vector<SegPtr> Segments;
- void writeHeader(llvm::FileOutputBuffer &Out) const;
- void writeProgramHeaders(llvm::FileOutputBuffer &Out) const;
- void writeSectionData(llvm::FileOutputBuffer &Out) const;
- void writeSectionHeaders(llvm::FileOutputBuffer &Out) const;
+ void writeHeader(FileOutputBuffer &Out) const;
+ void writeProgramHeaders(FileOutputBuffer &Out) const;
+ void writeSectionData(FileOutputBuffer &Out) const;
+ void writeSectionHeaders(FileOutputBuffer &Out) const;
public:
uint8_t Ident[16];
uint32_t Flags;
bool WriteSectionHeaders = true;
- Object(const llvm::object::ELFObjectFile<ELFT> &Obj);
+ Object(const object::ELFObjectFile<ELFT> &Obj);
+ virtual ~Object() = default;
+
void removeSections(std::function<bool(const SectionBase &)> ToRemove);
virtual size_t totalSize() const = 0;
virtual void finalize() = 0;
- virtual void write(llvm::FileOutputBuffer &Out) const = 0;
- virtual ~Object() = default;
+ virtual void write(FileOutputBuffer &Out) const = 0;
};
template <class ELFT> class ELFObject : public Object<ELFT> {
private:
- typedef std::unique_ptr<SectionBase> SecPtr;
- typedef std::unique_ptr<Segment> SegPtr;
+ using SecPtr = std::unique_ptr<SectionBase>;
+ using SegPtr = std::unique_ptr<Segment>;
- typedef typename ELFT::Shdr Elf_Shdr;
- typedef typename ELFT::Ehdr Elf_Ehdr;
- typedef typename ELFT::Phdr Elf_Phdr;
+ using Elf_Shdr = typename ELFT::Shdr;
+ using Elf_Ehdr = typename ELFT::Ehdr;
+ using Elf_Phdr = typename ELFT::Phdr;
void sortSections();
void assignOffsets();
public:
- ELFObject(const llvm::object::ELFObjectFile<ELFT> &Obj) : Object<ELFT>(Obj) {}
+ ELFObject(const object::ELFObjectFile<ELFT> &Obj) : Object<ELFT>(Obj) {}
+
void finalize() override;
size_t totalSize() const override;
- void write(llvm::FileOutputBuffer &Out) const override;
+ void write(FileOutputBuffer &Out) const override;
};
template <class ELFT> class BinaryObject : public Object<ELFT> {
private:
- typedef std::unique_ptr<SectionBase> SecPtr;
- typedef std::unique_ptr<Segment> SegPtr;
+ using SecPtr = std::unique_ptr<SectionBase>;
+ using SegPtr = std::unique_ptr<Segment>;
uint64_t TotalSize;
public:
- BinaryObject(const llvm::object::ELFObjectFile<ELFT> &Obj)
- : Object<ELFT>(Obj) {}
+ BinaryObject(const object::ELFObjectFile<ELFT> &Obj) : Object<ELFT>(Obj) {}
+
void finalize() override;
size_t totalSize() const override;
- void write(llvm::FileOutputBuffer &Out) const override;
+ void write(FileOutputBuffer &Out) const override;
};
-#endif
+
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_OBJCOPY_OBJECT_H
-//===- llvm-objcopy.cpp -----------------------------------------*- C++ -*-===//
+//===- llvm-objcopy.cpp ---------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "llvm-objcopy.h"
#include "Object.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Support/ToolOutputFile.h"
-
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+#include <functional>
+#include <iterator>
#include <memory>
#include <string>
#include <system_error>
+#include <utility>
using namespace llvm;
using namespace object;
exit(1);
}
-LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, llvm::Error E) {
+LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, Error E) {
assert(E);
std::string Buf;
raw_string_ostream OS(Buf);
errs() << ToolName << ": '" << File << "': " << Buf;
exit(1);
}
-}
-cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input>"));
-cl::opt<std::string> OutputFilename(cl::Positional, cl::desc("<output>"),
+} // end namespace llvm
+
+static cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input>"));
+static cl::opt<std::string> OutputFilename(cl::Positional, cl::desc("<output>"),
cl::init("-"));
-cl::opt<std::string>
+static cl::opt<std::string>
OutputFormat("O", cl::desc("set output format to one of the following:"
"\n\tbinary"));
-cl::list<std::string> ToRemove("remove-section",
- cl::desc("Remove a specific section"));
-cl::alias ToRemoveA("R", cl::desc("Alias for remove-section"),
- cl::aliasopt(ToRemove));
-cl::opt<bool> StripSections("strip-sections",
- cl::desc("Remove all section headers"));
-
-typedef std::function<bool(const SectionBase &Sec)> SectionPred;
+static cl::list<std::string> ToRemove("remove-section",
+ cl::desc("Remove a specific section"));
+static cl::alias ToRemoveA("R", cl::desc("Alias for remove-section"),
+ cl::aliasopt(ToRemove));
+static cl::opt<bool> StripSections("strip-sections",
+ cl::desc("Remove all section headers"));
+
+using SectionPred = std::function<bool(const SectionBase &Sec)>;
void CopyBinary(const ELFObjectFile<ELF64LE> &ObjFile) {
std::unique_ptr<FileOutputBuffer> Buffer;
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_OBJCOPY_H
-#define LLVM_OBJCOPY_H
+
+#ifndef LLVM_TOOLS_OBJCOPY_OBJCOPY_H
+#define LLVM_TOOLS_OBJCOPY_OBJCOPY_H
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
namespace llvm {
OS.flush();
error(Buf);
}
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_OBJCOPY_OBJCOPY_H