mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-23 05:52:40 +00:00
Add support for dumping section headers to llvm-objdump. This uses the same
flags as binutils objdump but the output is different, not just in format but also showing different sections. Compare its results against readelf, not objdump. llvm-svn: 141579
This commit is contained in:
parent
0d908f3a85
commit
73e4d372d0
@ -126,6 +126,50 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// format_object4 - This is a templated helper class used by the format
|
||||||
|
/// function that captures the object to be formated and the format string. When
|
||||||
|
/// actually printed, this synthesizes the string into a temporary buffer
|
||||||
|
/// provided and returns whether or not it is big enough.
|
||||||
|
template <typename T1, typename T2, typename T3, typename T4>
|
||||||
|
class format_object4 : public format_object_base {
|
||||||
|
T1 Val1;
|
||||||
|
T2 Val2;
|
||||||
|
T3 Val3;
|
||||||
|
T4 Val4;
|
||||||
|
public:
|
||||||
|
format_object4(const char *fmt, const T1 &val1, const T2 &val2,
|
||||||
|
const T3 &val3, const T4 &val4)
|
||||||
|
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int snprint(char *Buffer, unsigned BufferSize) const {
|
||||||
|
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// format_object5 - This is a templated helper class used by the format
|
||||||
|
/// function that captures the object to be formated and the format string. When
|
||||||
|
/// actually printed, this synthesizes the string into a temporary buffer
|
||||||
|
/// provided and returns whether or not it is big enough.
|
||||||
|
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
|
class format_object5 : public format_object_base {
|
||||||
|
T1 Val1;
|
||||||
|
T2 Val2;
|
||||||
|
T3 Val3;
|
||||||
|
T4 Val4;
|
||||||
|
T5 Val5;
|
||||||
|
public:
|
||||||
|
format_object5(const char *fmt, const T1 &val1, const T2 &val2,
|
||||||
|
const T3 &val3, const T4 &val4, const T5 &val5)
|
||||||
|
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4),
|
||||||
|
Val5(val5) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int snprint(char *Buffer, unsigned BufferSize) const {
|
||||||
|
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// format - This is a helper function that is used to produce formatted output.
|
/// format - This is a helper function that is used to produce formatted output.
|
||||||
/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
|
/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -149,6 +193,24 @@ template <typename T1, typename T2, typename T3>
|
|||||||
return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3);
|
return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// format - This is a helper function that is used to produce formatted output.
|
||||||
|
/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
|
||||||
|
template <typename T1, typename T2, typename T3, typename T4>
|
||||||
|
inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
|
||||||
|
const T2 &Val2, const T3 &Val3,
|
||||||
|
const T4 &Val4) {
|
||||||
|
return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// format - This is a helper function that is used to produce formatted output.
|
||||||
|
/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
|
||||||
|
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
|
inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1,
|
||||||
|
const T2 &Val2, const T3 &Val3,
|
||||||
|
const T4 &Val4, const T5 &Val5) {
|
||||||
|
return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5);
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
16
test/Object/objdump-sectionheaders.test
Normal file
16
test/Object/objdump-sectionheaders.test
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
; RUN: llvm-objdump -h %p/TestObjectFiles/trivial-object-test.elf-x86-64 \
|
||||||
|
; RUN: | FileCheck %s
|
||||||
|
|
||||||
|
; To verify this, use readelf -S, not objdump -h. Binutils objdump filters the
|
||||||
|
; results in a way that we don't emulate.
|
||||||
|
|
||||||
|
; CHECK: Sections:
|
||||||
|
; CHECK: Idx Name Size Address Type
|
||||||
|
; CHECK: 0 000000000 00000000000000000
|
||||||
|
; CHECK: 1 .text 000000026 00000000000000000 TEXT DATA
|
||||||
|
; CHECK: 2 .rodata.str1.1 00000000d 00000000000000026 DATA
|
||||||
|
; CHECK: 3 .note.GNU-stack 000000000 00000000000000033
|
||||||
|
; CHECK: 4 .rela.text 000000048 00000000000000038
|
||||||
|
; CHECK: 5 .symtab 0000000c0 00000000000000080
|
||||||
|
; CHECK: 6 .strtab 000000033 00000000000000140
|
||||||
|
; CHECK: 7 .shstrtab 00000004b 00000000000000173
|
@ -73,6 +73,16 @@ cl::opt<std::string>
|
|||||||
llvm::ArchName("arch", cl::desc("Target arch to disassemble for, "
|
llvm::ArchName("arch", cl::desc("Target arch to disassemble for, "
|
||||||
"see -version for available targets"));
|
"see -version for available targets"));
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
SectionHeaders("section-headers", cl::desc("Display summaries of the headers "
|
||||||
|
"for each section."));
|
||||||
|
static cl::alias
|
||||||
|
SectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
|
||||||
|
cl::aliasopt(SectionHeaders));
|
||||||
|
static cl::alias
|
||||||
|
SectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
|
||||||
|
cl::aliasopt(SectionHeaders));
|
||||||
|
|
||||||
static StringRef ToolName;
|
static StringRef ToolName;
|
||||||
|
|
||||||
static bool error(error_code ec) {
|
static bool error(error_code ec) {
|
||||||
@ -281,11 +291,39 @@ static void PrintRelocations(const ObjectFile *o) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void PrintSectionHeaders(const ObjectFile *o) {
|
||||||
|
outs() << "Sections:\n"
|
||||||
|
"Idx Name Size Address Type\n";
|
||||||
|
error_code ec;
|
||||||
|
unsigned i = 0;
|
||||||
|
for (section_iterator si = o->begin_sections(), se = o->end_sections();
|
||||||
|
si != se; si.increment(ec)) {
|
||||||
|
if (error(ec)) return;
|
||||||
|
StringRef Name;
|
||||||
|
if (error(si->getName(Name))) return;
|
||||||
|
uint64_t Address;
|
||||||
|
if (error(si->getAddress(Address))) return;
|
||||||
|
uint64_t Size;
|
||||||
|
if (error(si->getSize(Size))) return;
|
||||||
|
bool Text, Data, BSS;
|
||||||
|
if (error(si->isText(Text))) return;
|
||||||
|
if (error(si->isData(Data))) return;
|
||||||
|
if (error(si->isBSS(BSS))) return;
|
||||||
|
std::string Type = (std::string(Text ? "TEXT " : "") +
|
||||||
|
(Data ? "DATA " : "") + (BSS ? "BSS" : ""));
|
||||||
|
outs() << format("%3d %-13s %09x %017x %s\n", i, Name.str().c_str(), Size,
|
||||||
|
Address, Type.c_str());
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void DumpObject(const ObjectFile *o) {
|
static void DumpObject(const ObjectFile *o) {
|
||||||
if (Disassemble)
|
if (Disassemble)
|
||||||
DisassembleObject(o);
|
DisassembleObject(o);
|
||||||
if (Relocations)
|
if (Relocations)
|
||||||
PrintRelocations(o);
|
PrintRelocations(o);
|
||||||
|
if (SectionHeaders)
|
||||||
|
PrintSectionHeaders(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Dump each object file in \a a;
|
/// @brief Dump each object file in \a a;
|
||||||
@ -356,7 +394,7 @@ int main(int argc, char **argv) {
|
|||||||
if (InputFilenames.size() == 0)
|
if (InputFilenames.size() == 0)
|
||||||
InputFilenames.push_back("a.out");
|
InputFilenames.push_back("a.out");
|
||||||
|
|
||||||
if (!Disassemble && !Relocations) {
|
if (!Disassemble && !Relocations && !SectionHeaders) {
|
||||||
cl::PrintHelpMessage();
|
cl::PrintHelpMessage();
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user