Add code to llvm-objdump so the -section option with -macho will dump literal

sections with the Mach-O S_{4,8,16}BYTE_LITERALS section types.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228465 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Kevin Enderby
2015-02-06 23:25:38 +00:00
parent 8650883afb
commit 4e96e52cbe
3 changed files with 202 additions and 6 deletions

View File

@ -539,13 +539,15 @@ static const char *GuessSymbolName(uint64_t value, SymbolAddressMap *AddrMap) {
static void DumpCstringSection(MachOObjectFile *O, const char *sect,
uint32_t sect_size, uint64_t sect_addr,
bool verbose) {
bool print_addresses) {
for (uint32_t i = 0; i < sect_size; i++) {
if (O->is64Bit())
outs() << format("0x%016" PRIx64, sect_addr + i) << " ";
else
outs() << format("0x%08" PRIx64, sect_addr + i) << " ";
for ( ; i < sect_size && sect[i] != '\0'; i++) {
if (print_addresses) {
if (O->is64Bit())
outs() << format("0x%016" PRIx64, sect_addr + i) << " ";
else
outs() << format("0x%08" PRIx64, sect_addr + i) << " ";
}
for (; i < sect_size && sect[i] != '\0'; i++) {
char p[2];
p[0] = sect[i];
p[1] = '\0';
@ -556,6 +558,123 @@ static void DumpCstringSection(MachOObjectFile *O, const char *sect,
}
}
static void DumpLiteral4(uint32_t l, float f) {
outs() << format("0x%08" PRIx32, l);
if ((l & 0x7f800000) != 0x7f800000)
outs() << format(" (%.16e)\n", f);
else {
if (l == 0x7f800000)
outs() << " (+Infinity)\n";
else if (l == 0xff800000)
outs() << " (-Infinity)\n";
else if ((l & 0x00400000) == 0x00400000)
outs() << " (non-signaling Not-a-Number)\n";
else
outs() << " (signaling Not-a-Number)\n";
}
}
static void DumpLiteral4Section(MachOObjectFile *O, const char *sect,
uint32_t sect_size, uint64_t sect_addr,
bool print_addresses) {
for (uint32_t i = 0; i < sect_size; i += sizeof(float)) {
if (print_addresses) {
if (O->is64Bit())
outs() << format("0x%016" PRIx64, sect_addr + i) << " ";
else
outs() << format("0x%08" PRIx64, sect_addr + i) << " ";
}
float f;
memcpy(&f, sect + i, sizeof(float));
if (O->isLittleEndian() != sys::IsLittleEndianHost)
sys::swapByteOrder(f);
uint32_t l;
memcpy(&l, sect + i, sizeof(uint32_t));
if (O->isLittleEndian() != sys::IsLittleEndianHost)
sys::swapByteOrder(l);
DumpLiteral4(l, f);
}
}
static void DumpLiteral8(MachOObjectFile *O, uint32_t l0, uint32_t l1,
double d) {
outs() << format("0x%08" PRIx32, l0) << " " << format("0x%08" PRIx32, l1);
uint32_t Hi, Lo;
if (O->isLittleEndian()) {
Hi = l1;
Lo = l0;
} else {
Hi = l0;
Lo = l1;
}
// Hi is the high word, so this is equivalent to if(isfinite(d))
if ((Hi & 0x7ff00000) != 0x7ff00000)
outs() << format(" (%.16e)\n", d);
else {
if (Hi == 0x7ff00000 && Lo == 0)
outs() << " (+Infinity)\n";
else if (Hi == 0xfff00000 && Lo == 0)
outs() << " (-Infinity)\n";
else if ((Hi & 0x00080000) == 0x00080000)
outs() << " (non-signaling Not-a-Number)\n";
else
outs() << " (signaling Not-a-Number)\n";
}
}
static void DumpLiteral8Section(MachOObjectFile *O, const char *sect,
uint32_t sect_size, uint64_t sect_addr,
bool print_addresses) {
for (uint32_t i = 0; i < sect_size; i += sizeof(double)) {
if (print_addresses) {
if (O->is64Bit())
outs() << format("0x%016" PRIx64, sect_addr + i) << " ";
else
outs() << format("0x%08" PRIx64, sect_addr + i) << " ";
}
double d;
memcpy(&d, sect + i, sizeof(double));
if (O->isLittleEndian() != sys::IsLittleEndianHost)
sys::swapByteOrder(d);
uint32_t l0, l1;
memcpy(&l0, sect + i, sizeof(uint32_t));
memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
if (O->isLittleEndian() != sys::IsLittleEndianHost) {
sys::swapByteOrder(l0);
sys::swapByteOrder(l1);
}
DumpLiteral8(O, l0, l1, d);
}
}
static void DumpLiteral16Section(MachOObjectFile *O, const char *sect,
uint32_t sect_size, uint64_t sect_addr,
bool print_addresses) {
for (uint32_t i = 0; i < sect_size; i += 16) {
if (print_addresses) {
if (O->is64Bit())
outs() << format("0x%016" PRIx64, sect_addr + i) << " ";
else
outs() << format("0x%08" PRIx64, sect_addr + i) << " ";
}
uint32_t l0, l1, l2, l3;
memcpy(&l0, sect + i, sizeof(uint32_t));
memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
memcpy(&l2, sect + i + 2 * sizeof(uint32_t), sizeof(uint32_t));
memcpy(&l3, sect + i + 3 * sizeof(uint32_t), sizeof(uint32_t));
if (O->isLittleEndian() != sys::IsLittleEndianHost) {
sys::swapByteOrder(l0);
sys::swapByteOrder(l1);
sys::swapByteOrder(l2);
sys::swapByteOrder(l3);
}
outs() << format("0x%08" PRIx32, l0) << " ";
outs() << format("0x%08" PRIx32, l1) << " ";
outs() << format("0x%08" PRIx32, l2) << " ";
outs() << format("0x%08" PRIx32, l3) << "\n";
}
}
static void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect,
uint32_t sect_size, uint64_t sect_addr,
SymbolAddressMap *AddrMap,
@ -698,6 +817,15 @@ static void DumpSectionContents(StringRef Filename, MachOObjectFile *O,
case MachO::S_CSTRING_LITERALS:
DumpCstringSection(O, sect, sect_size, sect_addr, verbose);
break;
case MachO::S_4BYTE_LITERALS:
DumpLiteral4Section(O, sect, sect_size, sect_addr, verbose);
break;
case MachO::S_8BYTE_LITERALS:
DumpLiteral8Section(O, sect, sect_size, sect_addr, verbose);
break;
case MachO::S_16BYTE_LITERALS:
DumpLiteral16Section(O, sect, sect_size, sect_addr, verbose);
break;
case MachO::S_MOD_INIT_FUNC_POINTERS:
case MachO::S_MOD_TERM_FUNC_POINTERS:
DumpInitTermPointerSection(O, sect, sect_size, sect_addr, &AddrMap,