diff options
author | Jordan Rupprecht <rupprecht@google.com> | 2019-10-15 18:13:20 +0000 |
---|---|---|
committer | Jordan Rupprecht <rupprecht@google.com> | 2019-10-15 18:13:20 +0000 |
commit | eb501b1fc17783f548e7d337521161cbd9ff7ddd (patch) | |
tree | 0e426d5940d4cf5d59d483cd144a1456c94a4728 /llvm/tools | |
parent | 621ce3790ba254256222addad60d818cb90ac831 (diff) | |
download | llvm-eb501b1fc17783f548e7d337521161cbd9ff7ddd.zip llvm-eb501b1fc17783f548e7d337521161cbd9ff7ddd.tar.gz llvm-eb501b1fc17783f548e7d337521161cbd9ff7ddd.tar.bz2 |
[llvm-objdump] Use a counter for llvm-objdump -h instead of the section index.
Summary:
When listing the index in `llvm-objdump -h`, use a zero-based counter instead of the actual section index (e.g. shdr->sh_index for ELF).
While this is effectively a noop for now (except one unit test for XCOFF), the index values will change in a future patch that filters certain sections out (e.g. symbol tables). See D68669 for more context. Note: the test case in `test/tools/llvm-objdump/X86/section-index.s` already covers the case of incrementing the section index counter when sections are skipped.
Reviewers: grimar, jhenderson, espindola
Reviewed By: grimar
Subscribers: emaste, sbc100, arichardson, aheejin, arphaman, seiya, llvm-commits, MaskRay
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D68848
llvm-svn: 374931
Diffstat (limited to 'llvm/tools')
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 53 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.h | 14 |
2 files changed, 54 insertions, 13 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 83344e7..6377d3b 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -342,14 +342,27 @@ static StringRef ToolName; typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy; -static bool shouldKeep(object::SectionRef S) { +namespace { +struct FilterResult { + // True if the section should not be skipped. + bool Keep; + + // True if the index counter should be incremented, even if the section should + // be skipped. For example, sections may be skipped if they are not included + // in the --section flag, but we still want those to count toward the section + // count. + bool IncrementIndex; +}; +} // namespace + +static FilterResult checkSectionFilter(object::SectionRef S) { if (FilterSections.empty()) - return true; + return {/*Keep=*/true, /*IncrementIndex=*/true}; Expected<StringRef> SecNameOrErr = S.getName(); if (!SecNameOrErr) { consumeError(SecNameOrErr.takeError()); - return false; + return {/*Keep=*/false, /*IncrementIndex=*/false}; } StringRef SecName = *SecNameOrErr; @@ -357,11 +370,26 @@ static bool shouldKeep(object::SectionRef S) { // no name (such as the section with index 0) here. if (!SecName.empty()) FoundSectionSet.insert(SecName); - return is_contained(FilterSections, SecName); + + // Only show the section if it's in the FilterSections list, but always + // increment so the indexing is stable. + return {/*Keep=*/is_contained(FilterSections, SecName), + /*IncrementIndex=*/true}; } -SectionFilter ToolSectionFilter(object::ObjectFile const &O) { - return SectionFilter([](object::SectionRef S) { return shouldKeep(S); }, O); +SectionFilter ToolSectionFilter(object::ObjectFile const &O, uint64_t *Idx) { + // Start at UINT64_MAX so that the first index returned after an increment is + // zero (after the unsigned wrap). + if (Idx) + *Idx = UINT64_MAX; + return SectionFilter( + [Idx](object::SectionRef S) { + FilterResult Result = checkSectionFilter(S); + if (Idx != nullptr && Result.IncrementIndex) + *Idx += 1; + return Result.Keep; + }, + O); } std::string getFileNameForError(const object::Archive::Child &C, @@ -967,7 +995,7 @@ getRelocsMap(object::ObjectFile const &Obj) { std::map<SectionRef, std::vector<RelocationRef>> Ret; for (SectionRef Sec : Obj.sections()) { section_iterator Relocated = Sec.getRelocatedSection(); - if (Relocated == Obj.section_end() || !shouldKeep(*Relocated)) + if (Relocated == Obj.section_end() || !checkSectionFilter(*Relocated).Keep) continue; std::vector<RelocationRef> &V = Ret[*Relocated]; for (const RelocationRef &R : Sec.relocations()) @@ -1676,7 +1704,8 @@ void printSectionHeaders(const ObjectFile *Obj) { << left_justify("Name", NameWidth) << " Size " << left_justify("VMA", AddressWidth) << " Type\n"; - for (const SectionRef &Section : ToolSectionFilter(*Obj)) { + uint64_t Idx; + for (const SectionRef &Section : ToolSectionFilter(*Obj, &Idx)) { StringRef Name = unwrapOrError(Section.getName(), Obj->getFileName()); uint64_t VMA = Section.getAddress(); if (shouldAdjustVA(Section)) @@ -1691,14 +1720,14 @@ void printSectionHeaders(const ObjectFile *Obj) { Type += Type.empty() ? "BSS" : " BSS"; if (HasLMAColumn) - outs() << format("%3d %-*s %08" PRIx64 " ", (unsigned)Section.getIndex(), - NameWidth, Name.str().c_str(), Size) + outs() << format("%3d %-*s %08" PRIx64 " ", Idx, NameWidth, + Name.str().c_str(), Size) << format_hex_no_prefix(VMA, AddressWidth) << " " << format_hex_no_prefix(getELFSectionLMA(Section), AddressWidth) << " " << Type << "\n"; else - outs() << format("%3d %-*s %08" PRIx64 " ", (unsigned)Section.getIndex(), - NameWidth, Name.str().c_str(), Size) + outs() << format("%3d %-*s %08" PRIx64 " ", Idx, NameWidth, + Name.str().c_str(), Size) << format_hex_no_prefix(VMA, AddressWidth) << " " << Type << "\n"; } outs() << "\n"; diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h index d36c4fd..43ce02a 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.h +++ b/llvm/tools/llvm-objdump/llvm-objdump.h @@ -31,6 +31,8 @@ extern cl::opt<bool> Demangle; typedef std::function<bool(llvm::object::SectionRef const &)> FilterPredicate; +/// A filtered iterator for SectionRefs that skips sections based on some given +/// predicate. class SectionFilterIterator { public: SectionFilterIterator(FilterPredicate P, @@ -60,6 +62,8 @@ private: llvm::object::section_iterator End; }; +/// Creates an iterator range of SectionFilterIterators for a given Object and +/// predicate. class SectionFilter { public: SectionFilter(FilterPredicate P, llvm::object::ObjectFile const &O) @@ -79,7 +83,15 @@ private: }; // Various helper functions. -SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O); + +/// Creates a SectionFilter with a standard predicate that conditionally skips +/// sections when the --section objdump flag is provided. +/// +/// Idx is an optional output parameter that keeps track of which section index +/// this is. This may be different than the actual section number, as some +/// sections may be filtered (e.g. symbol tables). +SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O, + uint64_t *Idx = nullptr); Error getELFRelocationValueString(const object::ELFObjectFileBase *Obj, const object::RelocationRef &Rel, |