mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-21 21:11:36 +00:00
Revert dsymutil -update commits
Revert "[dsymutil][test] Check the updated dSYM instead of companion file." Revert "[dsymutil] Upstream update feature." llvm-svn: 324493
This commit is contained in:
parent
6b278207aa
commit
6d4147311f
@ -40,9 +40,7 @@ OPTIONS
|
||||
|
||||
When used when creating a dSYM file, this option will suppress the emission of
|
||||
the .debug_inlines, .debug_pubnames, and .debug_pubtypes sections since
|
||||
dsymutil currently has better equivalents: .apple_names and .apple_types. When
|
||||
used in conjunction with --update option, this option will cause redundant
|
||||
accelerator tables to be removed.
|
||||
dsymutil currently has better equivalents: .apple_names and .apple_types.
|
||||
|
||||
.. option:: --no-odr
|
||||
|
||||
@ -74,12 +72,6 @@ OPTIONS
|
||||
|
||||
Dumps the symbol table found in *executable* or object file(s) and exits.
|
||||
|
||||
.. option:: -u, --update
|
||||
|
||||
Update an existing dSYM file to contain the latest accelerator tables and
|
||||
other DWARF optimizations. This option will rebuild the '.apple_names' and
|
||||
'.apple_types' hashed accelerator tables.
|
||||
|
||||
.. option:: -v, --verbose
|
||||
|
||||
Display verbose information when linking.
|
||||
|
@ -8,21 +8,6 @@ RUN: llvm-dsymutil -f -o - -oso-prepend-path=%p/.. %p/../Inputs/basic-archive.ma
|
||||
RUN: llvm-dsymutil -dump-debug-map -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 | llvm-dsymutil -f -y -o - - | llvm-dwarfdump -a - | FileCheck %s --check-prefix=CHECK --check-prefix=BASIC
|
||||
RUN: llvm-dsymutil -dump-debug-map -oso-prepend-path=%p/.. %p/../Inputs/basic-archive.macho.x86_64 | llvm-dsymutil -f -o - -y - | llvm-dwarfdump -a - | FileCheck %s --check-prefix=CHECK --check-prefix=ARCHIVE
|
||||
|
||||
# Update tests
|
||||
RUN: rm -rf %t.dir
|
||||
RUN: mkdir -p %t.dir
|
||||
RUN: cat %p/../Inputs/basic.macho.x86_64 > %t.dir/basic
|
||||
RUN: llvm-dsymutil -oso-prepend-path=%p/.. %t.dir/basic
|
||||
RUN: llvm-dwarfdump -a %t.dir/basic.dSYM | FileCheck %s
|
||||
RUN: llvm-dsymutil --update %t.dir/basic.dSYM
|
||||
RUN: llvm-dwarfdump -a %t.dir/basic.dSYM | FileCheck %s
|
||||
RUN: llvm-dsymutil -u %t.dir/basic.dSYM
|
||||
RUN: llvm-dwarfdump -a %t.dir/basic.dSYM | FileCheck %s
|
||||
RUN: llvm-dsymutil --update %t.dir/basic.dSYM -o %t.dir/updated.dSYM
|
||||
RUN: llvm-dwarfdump -a %t.dir/updated.dSYM | FileCheck %s
|
||||
RUN: llvm-dsymutil -f -u %t2 -o %t3
|
||||
RUN: llvm-dwarfdump -a %t3 | FileCheck %s
|
||||
|
||||
CHECK: file format Mach-O 64-bit x86-64
|
||||
|
||||
CHECK: debug_info contents
|
||||
|
@ -1,35 +0,0 @@
|
||||
RUN: llvm-dsymutil -oso-prepend-path=%p/.. %p/../Inputs/objc.macho.x86_64 -o %t.dSYM
|
||||
RUN: llvm-dsymutil -update %t.dSYM
|
||||
RUN: llvm-dwarfdump -apple-types -apple-objc %t.dSYM | FileCheck %s
|
||||
|
||||
CHECK: .apple_types contents:
|
||||
CHECK: Hash 0x2b5e6 [
|
||||
CHECK-NEXT: Name@0x145 {
|
||||
CHECK-NEXT: String: 0x00000066 "A"
|
||||
CHECK-NEXT: Data 0 [
|
||||
CHECK-NEXT: Atom[0]: 0x0000012d
|
||||
CHECK-NEXT: Atom[1]: 0x0013
|
||||
CHECK-NEXT: Atom[2]: 0x02
|
||||
CHECK-NEXT: Atom[3]: 0x0b87b15a
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: }
|
||||
CHECK-NEXT: ]
|
||||
|
||||
CHECK: .apple_objc contents:
|
||||
CHECK: Hash 0x2b5e6
|
||||
CHECK-NEXT: Name@0x38 {
|
||||
CHECK-NEXT: String: 0x00000066 "A"
|
||||
CHECK-NEXT: Data 0 [
|
||||
CHECK-NEXT: Atom[0]: 0x00000027
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: Data 1 [
|
||||
CHECK-NEXT: Atom[0]: 0x0000007a
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: }
|
||||
CHECK: Hash 0x3fa0f4b5
|
||||
CHECK-NEXT: Name@0x4c {
|
||||
CHECK-NEXT: String: 0x0000009d "A(Category)"
|
||||
CHECK-NEXT: Data 0 [
|
||||
CHECK-NEXT: Atom[0]: 0x0000007a
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: }
|
@ -14,7 +14,6 @@ HELP: -num-threads=<n>
|
||||
HELP: -o=<filename>
|
||||
HELP: -oso-prepend-path=<path>
|
||||
HELP: -symtab
|
||||
HELP: -update
|
||||
HELP: -verbose
|
||||
HELP: -verify
|
||||
HELP: -y
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include "llvm/Support/Chrono.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/YAMLTraits.h"
|
||||
@ -108,7 +107,7 @@ public:
|
||||
DebugMapObject &
|
||||
addDebugMapObject(StringRef ObjectFilePath,
|
||||
sys::TimePoint<std::chrono::seconds> Timestamp,
|
||||
uint8_t Type = llvm::MachO::N_OSO);
|
||||
uint8_t Type);
|
||||
|
||||
const Triple &getTriple() const { return BinaryTriple; }
|
||||
|
||||
|
@ -100,24 +100,6 @@ namespace dsymutil {
|
||||
|
||||
namespace {
|
||||
|
||||
/// Retrieve the section named \a SecName in \a Obj.
|
||||
///
|
||||
/// To accommodate for platform discrepancies, the name passed should be
|
||||
/// (for example) 'debug_info' to match either '__debug_info' or '.debug_info'.
|
||||
/// This function will strip the initial platform-specific characters.
|
||||
static Optional<object::SectionRef>
|
||||
getSectionByName(const object::ObjectFile &Obj, StringRef SecName) {
|
||||
for (const object::SectionRef &Section : Obj.sections()) {
|
||||
StringRef SectionName;
|
||||
Section.getName(SectionName);
|
||||
SectionName = SectionName.substr(SectionName.find_first_not_of("._"));
|
||||
if (SectionName != SecName)
|
||||
continue;
|
||||
return Section;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
template <typename KeyT, typename ValT>
|
||||
using HalfOpenIntervalMap =
|
||||
IntervalMap<KeyT, ValT, IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
|
||||
@ -509,48 +491,12 @@ private:
|
||||
std::string ClangModuleName;
|
||||
};
|
||||
|
||||
/// Check if the DIE at \p Idx is in the scope of a function.
|
||||
static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
|
||||
while (Idx) {
|
||||
if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram)
|
||||
return true;
|
||||
Idx = U.getInfo(Idx).ParentIdx;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
void CompileUnit::markEverythingAsKept() {
|
||||
unsigned Idx = 0;
|
||||
|
||||
setHasInterestingContent();
|
||||
|
||||
for (auto &I : Info) {
|
||||
// Mark everything that wasn't explicit marked for pruning.
|
||||
for (auto &I : Info)
|
||||
// Mark everything that wasn't explicity marked for pruning.
|
||||
I.Keep = !I.Prune;
|
||||
auto DIE = OrigUnit.getDIEAtIndex(Idx++);
|
||||
|
||||
// Try to guess which DIEs must go to the accelerator tables. We do that
|
||||
// just for variables, because functions will be handled depending on
|
||||
// whether they carry a DW_AT_low_pc attribute or not.
|
||||
if (DIE.getTag() != dwarf::DW_TAG_variable &&
|
||||
DIE.getTag() != dwarf::DW_TAG_constant)
|
||||
continue;
|
||||
|
||||
Optional<DWARFFormValue> Value;
|
||||
if (!(Value = DIE.find(dwarf::DW_AT_location))) {
|
||||
if ((Value = DIE.find(dwarf::DW_AT_const_value)) &&
|
||||
!inFunctionScope(*this, I.ParentIdx))
|
||||
I.InDebugMap = true;
|
||||
continue;
|
||||
}
|
||||
if (auto Block = Value->getAsBlock()) {
|
||||
if (Block->size() > OrigUnit.getAddressByteSize() &&
|
||||
(*Block)[0] == dwarf::DW_OP_addr)
|
||||
I.InDebugMap = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t CompileUnit::computeNextUnitOffset() {
|
||||
@ -722,9 +668,6 @@ public:
|
||||
std::vector<DWARFDebugLine::Row> &Rows,
|
||||
unsigned AdddressSize);
|
||||
|
||||
/// Copy over the debug sections that are not modified when updating.
|
||||
void copyInvariantDebugSection(const object::ObjectFile &Obj, LinkOptions &);
|
||||
|
||||
uint32_t getLineSectionSize() const { return LineSectionSize; }
|
||||
|
||||
/// Emit the .debug_pubnames contribution for \p Unit.
|
||||
@ -1257,32 +1200,6 @@ void DwarfStreamer::emitLineTableForUnit(MCDwarfLineTableParams Params,
|
||||
MS->EmitLabel(LineEndSym);
|
||||
}
|
||||
|
||||
static void emitSectionContents(const object::ObjectFile &Obj,
|
||||
StringRef SecName, MCStreamer *MS) {
|
||||
StringRef Contents;
|
||||
if (auto Sec = getSectionByName(Obj, SecName))
|
||||
if (!Sec->getContents(Contents))
|
||||
MS->EmitBytes(Contents);
|
||||
}
|
||||
|
||||
void DwarfStreamer::copyInvariantDebugSection(const object::ObjectFile &Obj,
|
||||
LinkOptions &Options) {
|
||||
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection());
|
||||
emitSectionContents(Obj, "debug_line", MS);
|
||||
|
||||
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
|
||||
emitSectionContents(Obj, "debug_loc", MS);
|
||||
|
||||
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
|
||||
emitSectionContents(Obj, "debug_ranges", MS);
|
||||
|
||||
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection());
|
||||
emitSectionContents(Obj, "debug_frame", MS);
|
||||
|
||||
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
|
||||
emitSectionContents(Obj, "debug_aranges", MS);
|
||||
}
|
||||
|
||||
/// Emit the pubnames or pubtypes section contribution for \p
|
||||
/// Unit into \p Sec. The data is provided in \p Names.
|
||||
void DwarfStreamer::emitPubSectionForUnit(
|
||||
@ -1612,8 +1529,8 @@ private:
|
||||
/// it to \p Die.
|
||||
/// \returns the size of the new attribute.
|
||||
unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
|
||||
const DWARFFormValue &Val, const DWARFUnit &U,
|
||||
AttributesInfo &Info);
|
||||
const DWARFFormValue &Val,
|
||||
const DWARFUnit &U);
|
||||
|
||||
/// Clone an attribute referencing another DIE and add
|
||||
/// it to \p Die.
|
||||
@ -2704,18 +2621,12 @@ void DwarfLinker::AssignAbbrev(DIEAbbrev &Abbrev) {
|
||||
unsigned DwarfLinker::DIECloner::cloneStringAttribute(DIE &Die,
|
||||
AttributeSpec AttrSpec,
|
||||
const DWARFFormValue &Val,
|
||||
const DWARFUnit &U,
|
||||
AttributesInfo &Info) {
|
||||
const DWARFUnit &U) {
|
||||
// Switch everything to out of line strings.
|
||||
const char *String = *Val.getAsCString();
|
||||
auto StringEntry = Linker.StringPool.getEntry(String);
|
||||
if (AttrSpec.Attr == dwarf::DW_AT_name)
|
||||
Info.Name = StringEntry;
|
||||
else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name ||
|
||||
AttrSpec.Attr == dwarf::DW_AT_linkage_name)
|
||||
Info.MangledName = StringEntry;
|
||||
unsigned Offset = Linker.StringPool.getStringOffset(String);
|
||||
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_strp,
|
||||
DIEInteger(StringEntry.getOffset()));
|
||||
DIEInteger(Offset));
|
||||
return 4;
|
||||
}
|
||||
|
||||
@ -2838,14 +2749,6 @@ unsigned DwarfLinker::DIECloner::cloneAddressAttribute(
|
||||
const CompileUnit &Unit, AttributesInfo &Info) {
|
||||
uint64_t Addr = *Val.getAsAddress();
|
||||
|
||||
if (LLVM_UNLIKELY(Linker.Options.Update)) {
|
||||
if (AttrSpec.Attr == dwarf::DW_AT_low_pc)
|
||||
Info.HasLowPc = true;
|
||||
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
|
||||
dwarf::Form(AttrSpec.Form), DIEInteger(Addr));
|
||||
return Unit.getOrigUnit().getAddressByteSize();
|
||||
}
|
||||
|
||||
if (AttrSpec.Attr == dwarf::DW_AT_low_pc) {
|
||||
if (Die.getTag() == dwarf::DW_TAG_inlined_subroutine ||
|
||||
Die.getTag() == dwarf::DW_TAG_lexical_block)
|
||||
@ -2886,26 +2789,6 @@ unsigned DwarfLinker::DIECloner::cloneScalarAttribute(
|
||||
AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize,
|
||||
AttributesInfo &Info) {
|
||||
uint64_t Value;
|
||||
|
||||
if (LLVM_UNLIKELY(Linker.Options.Update)) {
|
||||
if (auto OptionalValue = Val.getAsUnsignedConstant())
|
||||
Value = *OptionalValue;
|
||||
else if (auto OptionalValue = Val.getAsSignedConstant())
|
||||
Value = *OptionalValue;
|
||||
else if (auto OptionalValue = Val.getAsSectionOffset())
|
||||
Value = *OptionalValue;
|
||||
else {
|
||||
Linker.reportWarning(
|
||||
"Unsupported scalar attribute form. Dropping attribute.", &InputDIE);
|
||||
return 0;
|
||||
}
|
||||
if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
|
||||
Info.IsDeclaration = true;
|
||||
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
|
||||
dwarf::Form(AttrSpec.Form), DIEInteger(Value));
|
||||
return AttrSize;
|
||||
}
|
||||
|
||||
if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
|
||||
Die.getTag() == dwarf::DW_TAG_compile_unit) {
|
||||
if (Unit.getLowPc() == -1ULL)
|
||||
@ -2956,7 +2839,7 @@ unsigned DwarfLinker::DIECloner::cloneAttribute(
|
||||
switch (AttrSpec.Form) {
|
||||
case dwarf::DW_FORM_strp:
|
||||
case dwarf::DW_FORM_string:
|
||||
return cloneStringAttribute(Die, AttrSpec, Val, U, Info);
|
||||
return cloneStringAttribute(Die, AttrSpec, Val, U);
|
||||
case dwarf::DW_FORM_ref_addr:
|
||||
case dwarf::DW_FORM_ref1:
|
||||
case dwarf::DW_FORM_ref2:
|
||||
@ -3225,14 +3108,13 @@ DIE *DwarfLinker::DIECloner::cloneDIE(
|
||||
|
||||
if (Abbrev->getTag() == dwarf::DW_TAG_subprogram) {
|
||||
Flags |= TF_InFunctionScope;
|
||||
if (!Info.InDebugMap && LLVM_LIKELY(!Options.Update))
|
||||
if (!Info.InDebugMap)
|
||||
Flags |= TF_SkipPC;
|
||||
}
|
||||
|
||||
bool Copied = false;
|
||||
for (const auto &AttrSpec : Abbrev->attributes()) {
|
||||
if (LLVM_LIKELY(!Options.Update) &&
|
||||
shouldSkipAttribute(AttrSpec, Die->getTag(), Info.InDebugMap,
|
||||
if (shouldSkipAttribute(AttrSpec, Die->getTag(), Info.InDebugMap,
|
||||
Flags & TF_SkipPC, Flags & TF_InFunctionScope)) {
|
||||
DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
|
||||
U.getFormParams());
|
||||
@ -3945,18 +3827,13 @@ void DwarfLinker::DIECloner::cloneAllCompileUnits(DWARFContext &DwarfContext) {
|
||||
Linker.OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset();
|
||||
if (Linker.Options.NoOutput)
|
||||
continue;
|
||||
|
||||
if (LLVM_LIKELY(!Linker.Options.Update)) {
|
||||
// FIXME: for compatibility with the classic dsymutil, we emit an empty
|
||||
// line table for the unit, even if the unit doesn't actually exist in
|
||||
// the DIE tree.
|
||||
Linker.patchLineTableForUnit(*CurrentUnit, DwarfContext);
|
||||
Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
|
||||
Linker.patchRangesForUnit(*CurrentUnit, DwarfContext);
|
||||
Linker.Streamer->emitLocationsForUnit(*CurrentUnit, DwarfContext);
|
||||
} else {
|
||||
Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
|
||||
}
|
||||
// FIXME: for compatibility with the classic dsymutil, we emit
|
||||
// an empty line table for the unit, even if the unit doesn't
|
||||
// actually exist in the DIE tree.
|
||||
Linker.patchLineTableForUnit(*CurrentUnit, DwarfContext);
|
||||
Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
|
||||
Linker.patchRangesForUnit(*CurrentUnit, DwarfContext);
|
||||
Linker.Streamer->emitLocationsForUnit(*CurrentUnit, DwarfContext);
|
||||
}
|
||||
|
||||
if (Linker.Options.NoOutput)
|
||||
@ -3964,8 +3841,7 @@ void DwarfLinker::DIECloner::cloneAllCompileUnits(DWARFContext &DwarfContext) {
|
||||
|
||||
// Emit all the compile unit's debug information.
|
||||
for (auto &CurrentUnit : CompileUnits) {
|
||||
if (LLVM_LIKELY(!Linker.Options.Update))
|
||||
Linker.generateUnitRanges(*CurrentUnit);
|
||||
Linker.generateUnitRanges(*CurrentUnit);
|
||||
CurrentUnit->fixupForwardReferences();
|
||||
Linker.Streamer->emitCompileUnitHeader(*CurrentUnit);
|
||||
if (!CurrentUnit->getOutputUnitDIE())
|
||||
@ -4024,8 +3900,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
|
||||
// Look for relocations that correspond to debug map entries.
|
||||
RelocationManager RelocMgr(*this);
|
||||
if (LLVM_LIKELY(!Options.Update) &&
|
||||
!RelocMgr.findValidRelocsInDebugInfo(*ErrOrObj, *Obj)) {
|
||||
if (!RelocMgr.findValidRelocsInDebugInfo(*ErrOrObj, *Obj)) {
|
||||
if (Options.Verbose)
|
||||
outs() << "No valid relocations found. Skipping.\n";
|
||||
continue;
|
||||
@ -4046,10 +3921,9 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
CUDie.dump(outs(), 0, DumpOpts);
|
||||
}
|
||||
|
||||
if (!CUDie || LLVM_UNLIKELY(Options.Update) ||
|
||||
!registerModuleReference(CUDie, *CU, ModuleMap)) {
|
||||
Units.push_back(llvm::make_unique<CompileUnit>(
|
||||
*CU, UnitID++, !Options.NoODR && !Options.Update, ""));
|
||||
if (!registerModuleReference(CUDie, *CU, ModuleMap)) {
|
||||
Units.push_back(llvm::make_unique<CompileUnit>(*CU, UnitID++,
|
||||
!Options.NoODR, ""));
|
||||
maybeUpdateMaxDwarfVersion(CU->getVersion());
|
||||
}
|
||||
}
|
||||
@ -4061,27 +3935,21 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
|
||||
// Then mark all the DIEs that need to be present in the linked
|
||||
// output and collect some information about them. Note that this
|
||||
// loop can not be merged with the previous one because cross-CU
|
||||
// loop can not be merged with the previous one becaue cross-cu
|
||||
// references require the ParentIdx to be setup for every CU in
|
||||
// the object file before calling this.
|
||||
if (LLVM_UNLIKELY(Options.Update)) {
|
||||
for (auto &CurrentUnit : Units)
|
||||
CurrentUnit->markEverythingAsKept();
|
||||
Streamer->copyInvariantDebugSection(*ErrOrObj, Options);
|
||||
} else {
|
||||
for (auto &CurrentUnit : Units)
|
||||
lookForDIEsToKeep(RelocMgr, CurrentUnit->getOrigUnit().getUnitDIE(),
|
||||
*Obj, *CurrentUnit, 0);
|
||||
}
|
||||
for (auto &CurrentUnit : Units)
|
||||
lookForDIEsToKeep(RelocMgr, CurrentUnit->getOrigUnit().getUnitDIE(), *Obj,
|
||||
*CurrentUnit, 0);
|
||||
|
||||
// The calls to applyValidRelocs inside cloneDIE will walk the
|
||||
// reloc array again (in the same way findValidRelocsInDebugInfo()
|
||||
// did). We need to reset the NextValidReloc index to the beginning.
|
||||
RelocMgr.resetValidRelocs();
|
||||
if (RelocMgr.hasValidRelocs() || LLVM_UNLIKELY(Options.Update))
|
||||
if (RelocMgr.hasValidRelocs())
|
||||
DIECloner(*this, RelocMgr, DIEAlloc, Units, Options)
|
||||
.cloneAllCompileUnits(*DwarfContext);
|
||||
if (!Options.NoOutput && !Units.empty() && LLVM_LIKELY(!Options.Update))
|
||||
if (!Options.NoOutput && !Units.empty())
|
||||
patchFrameInfoForObject(*Obj, *DwarfContext,
|
||||
Units[0]->getOrigUnit().getAddressByteSize());
|
||||
|
||||
|
@ -80,21 +80,10 @@ static opt<bool> Minimize(
|
||||
desc("When used when creating a dSYM file, this option will suppress\n"
|
||||
"the emission of the .debug_inlines, .debug_pubnames, and\n"
|
||||
".debug_pubtypes sections since dsymutil currently has better\n"
|
||||
"equivalents: .apple_names and .apple_types. When used in\n"
|
||||
"conjunction with --update option, this option will cause redundant\n"
|
||||
"accelerator tables to be removed."),
|
||||
"equivalents: .apple_names and .apple_types."),
|
||||
init(false), cat(DsymCategory));
|
||||
static alias MinimizeA("z", desc("Alias for --minimize"), aliasopt(Minimize));
|
||||
|
||||
static opt<bool> Update(
|
||||
"update",
|
||||
desc("Updates existing dSYM files to contain the latest accelerator\n"
|
||||
"tables and other DWARF optimizations. This option will currently\n"
|
||||
"add the new .apple_names and .apple_types hashed accelerator\n"
|
||||
"tables."),
|
||||
init(false), cat(DsymCategory));
|
||||
static alias UpdateA("u", desc("Alias for --update"), aliasopt(Update));
|
||||
|
||||
static opt<unsigned> NumThreads(
|
||||
"num-threads",
|
||||
desc("Specifies the maximum number (n) of simultaneous threads to use\n"
|
||||
@ -241,12 +230,8 @@ static bool verify(llvm::StringRef OutputFile, llvm::StringRef Arch) {
|
||||
}
|
||||
|
||||
static std::string getOutputFileName(llvm::StringRef InputFile) {
|
||||
// When updating, do in place replacement.
|
||||
if (OutputFileOpt.empty() && Update)
|
||||
return InputFile;
|
||||
|
||||
// If a flat dSYM has been requested, things are pretty simple.
|
||||
if (FlatOut) {
|
||||
// If a flat dSYM has been requested, things are pretty simple.
|
||||
if (OutputFileOpt.empty()) {
|
||||
if (InputFile == "-")
|
||||
return "a.out.dwarf";
|
||||
@ -284,76 +269,6 @@ static Expected<sys::fs::TempFile> createTempFile() {
|
||||
return sys::fs::TempFile::create(TmpModel);
|
||||
}
|
||||
|
||||
/// Parses the command line options into the LinkOptions struct and performs
|
||||
/// some sanity checking. Returns an error in case the latter fails.
|
||||
static Expected<LinkOptions> getOptions() {
|
||||
LinkOptions Options;
|
||||
|
||||
Options.Verbose = Verbose;
|
||||
Options.NoOutput = NoOutput;
|
||||
Options.NoODR = NoODR;
|
||||
Options.Minimize = Minimize;
|
||||
Options.Update = Update;
|
||||
Options.NoTimestamp = NoTimestamp;
|
||||
Options.PrependPath = OsoPrependPath;
|
||||
|
||||
if (Options.Update && std::find(InputFiles.begin(), InputFiles.end(), "-") !=
|
||||
InputFiles.end()) {
|
||||
// FIXME: We cannot use stdin for an update because stdin will be
|
||||
// consumed by the BinaryHolder during the debugmap parsing, and
|
||||
// then we will want to consume it again in DwarfLinker. If we
|
||||
// used a unique BinaryHolder object that could cache multiple
|
||||
// binaries this restriction would go away.
|
||||
return make_error<StringError>(
|
||||
"error: standard input cannot be used as input for a dSYM update.",
|
||||
inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
return Options;
|
||||
}
|
||||
|
||||
/// Return a list of input files. This function has logic for dealing with the
|
||||
/// special case where we might have dSYM bundles as input. The function
|
||||
/// returns an error when the directory structure doesn't match that of a dSYM
|
||||
/// bundle.
|
||||
static Expected<std::vector<std::string>> getInputs(bool DsymAsInput) {
|
||||
if (!DsymAsInput)
|
||||
return InputFiles;
|
||||
|
||||
// If we are updating, we might get dSYM bundles as input.
|
||||
std::vector<std::string> Inputs;
|
||||
for (const auto &Input : InputFiles) {
|
||||
if (!llvm::sys::fs::is_directory(Input)) {
|
||||
Inputs.push_back(Input);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make sure that we're dealing with a dSYM bundle.
|
||||
std::string dSYMDir = Input + "/Contents/Resources/DWARF";
|
||||
if (!llvm::sys::fs::is_directory(dSYMDir))
|
||||
return make_error<StringError>(
|
||||
Input + " is a directory, but doesn't look like a dSYM bundle.",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
// Create a directory iterator to iterate over all the entries in the
|
||||
// bundle.
|
||||
std::error_code EC;
|
||||
llvm::sys::fs::directory_iterator DirIt(dSYMDir, EC);
|
||||
llvm::sys::fs::directory_iterator DirEnd;
|
||||
if (EC)
|
||||
return errorCodeToError(EC);
|
||||
|
||||
// Add each entry to the list of inputs.
|
||||
while (DirIt != DirEnd) {
|
||||
Inputs.push_back(DirIt->path());
|
||||
DirIt.increment(EC);
|
||||
if (EC)
|
||||
return errorCodeToError(EC);
|
||||
}
|
||||
}
|
||||
return Inputs;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct TempFileVector {
|
||||
std::vector<sys::fs::TempFile> Files;
|
||||
@ -370,6 +285,7 @@ int main(int argc, char **argv) {
|
||||
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
|
||||
llvm::PrettyStackTraceProgram StackPrinter(argc, argv);
|
||||
llvm::llvm_shutdown_obj Shutdown;
|
||||
LinkOptions Options;
|
||||
void *P = (void *)(intptr_t)getOutputFileName;
|
||||
std::string SDKPath = llvm::sys::fs::getMainExecutable(argv[0], P);
|
||||
SDKPath = llvm::sys::path::parent_path(SDKPath);
|
||||
@ -392,29 +308,24 @@ int main(int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto OptionsOrErr = getOptions();
|
||||
if (!OptionsOrErr) {
|
||||
errs() << "error: " << toString(OptionsOrErr.takeError());
|
||||
return 1;
|
||||
}
|
||||
Options.Verbose = Verbose;
|
||||
Options.NoOutput = NoOutput;
|
||||
Options.NoODR = NoODR;
|
||||
Options.Minimize = Minimize;
|
||||
Options.NoTimestamp = NoTimestamp;
|
||||
Options.PrependPath = OsoPrependPath;
|
||||
|
||||
llvm::InitializeAllTargetInfos();
|
||||
llvm::InitializeAllTargetMCs();
|
||||
llvm::InitializeAllTargets();
|
||||
llvm::InitializeAllAsmPrinters();
|
||||
|
||||
auto InputsOrErr = getInputs(OptionsOrErr->Update);
|
||||
if (!InputsOrErr) {
|
||||
errs() << "error: " << toString(InputsOrErr.takeError()) << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!FlatOut && OutputFileOpt == "-") {
|
||||
llvm::errs() << "error: cannot emit to standard output without --flat\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (InputsOrErr->size() > 1 && FlatOut && !OutputFileOpt.empty()) {
|
||||
if (InputFiles.size() > 1 && FlatOut && !OutputFileOpt.empty()) {
|
||||
llvm::errs() << "error: cannot use -o with multiple inputs in flat mode\n";
|
||||
return 1;
|
||||
}
|
||||
@ -426,7 +337,7 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (auto &InputFile : *InputsOrErr) {
|
||||
for (auto &InputFile : InputFiles) {
|
||||
// Dump the symbol table for each input file and requested arch
|
||||
if (DumpStab) {
|
||||
if (!dumpStab(InputFile, ArchFlags, OsoPrependPath))
|
||||
@ -443,15 +354,6 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (OptionsOrErr->Update) {
|
||||
// The debug map should be empty. Add one object file corresponding to
|
||||
// the input file.
|
||||
for (auto &Map : *DebugMapPtrsOrErr)
|
||||
Map->addDebugMapObject(InputFile,
|
||||
llvm::sys::TimePoint<std::chrono::seconds>());
|
||||
}
|
||||
|
||||
// Ensure that the debug map is not empty (anymore).
|
||||
if (DebugMapPtrsOrErr->empty()) {
|
||||
llvm::errs() << "error: no architecture to link\n";
|
||||
return 1;
|
||||
@ -467,10 +369,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
// If there is more than one link to execute, we need to generate
|
||||
// temporary files.
|
||||
bool NeedsTempFiles =
|
||||
!DumpDebugMap && (OutputFileOpt != "-") &&
|
||||
(DebugMapPtrsOrErr->size() != 1 || OptionsOrErr->Update);
|
||||
|
||||
bool NeedsTempFiles = !DumpDebugMap && (*DebugMapPtrsOrErr).size() != 1;
|
||||
llvm::SmallVector<MachOUtils::ArchAndFilename, 4> TempFiles;
|
||||
TempFileVector TempFileStore;
|
||||
std::atomic_char AllOK(1);
|
||||
@ -513,7 +412,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
auto LinkLambda = [&,
|
||||
OutputFile](std::shared_ptr<raw_fd_ostream> Stream) {
|
||||
AllOK.fetch_and(linkDwarf(*Stream, *Map, *OptionsOrErr));
|
||||
AllOK.fetch_and(linkDwarf(*Stream, *Map, Options));
|
||||
Stream->flush();
|
||||
if (Verify && !NoOutput)
|
||||
AllOK.fetch_and(verify(OutputFile, Map->getTriple().getArchName()));
|
||||
@ -535,7 +434,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (NeedsTempFiles &&
|
||||
!MachOUtils::generateUniversalBinary(
|
||||
TempFiles, getOutputFileName(InputFile), *OptionsOrErr, SDKPath))
|
||||
TempFiles, getOutputFileName(InputFile), Options, SDKPath))
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -37,10 +37,7 @@ struct LinkOptions {
|
||||
bool NoOutput = false;
|
||||
|
||||
/// Do not unique types according to ODR
|
||||
bool NoODR = false;
|
||||
|
||||
/// Update
|
||||
bool Update = false;
|
||||
bool NoODR;
|
||||
|
||||
/// Minimize
|
||||
bool Minimize = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user