aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools
diff options
context:
space:
mode:
authorJordan Rupprecht <rupprecht@google.com>2019-10-15 18:13:20 +0000
committerJordan Rupprecht <rupprecht@google.com>2019-10-15 18:13:20 +0000
commiteb501b1fc17783f548e7d337521161cbd9ff7ddd (patch)
tree0e426d5940d4cf5d59d483cd144a1456c94a4728 /llvm/tools
parent621ce3790ba254256222addad60d818cb90ac831 (diff)
downloadllvm-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.cpp53
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h14
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,