+static void PrintRelocations(const ObjectFile *o) {
+ error_code ec;
+ for (section_iterator si = o->begin_sections(), se = o->end_sections();
+ si != se; si.increment(ec)){
+ if (error(ec)) return;
+ if (si->begin_relocations() == si->end_relocations())
+ continue;
+ StringRef secname;
+ if (error(si->getName(secname))) continue;
+ outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
+ for (relocation_iterator ri = si->begin_relocations(),
+ re = si->end_relocations();
+ ri != re; ri.increment(ec)) {
+ if (error(ec)) return;
+
+ bool hidden;
+ uint64_t address;
+ SmallString<32> relocname;
+ SmallString<32> valuestr;
+ if (error(ri->getHidden(hidden))) continue;
+ if (hidden) continue;
+ if (error(ri->getTypeName(relocname))) continue;
+ if (error(ri->getOffset(address))) continue;
+ if (error(ri->getValueString(valuestr))) continue;
+ outs() << address << " " << relocname << " " << valuestr << "\n";
+ }
+ outs() << "\n";
+ }
+}
+
+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 %08" PRIx64 " %016" PRIx64 " %s\n",
+ i, Name.str().c_str(), Size, Address, Type.c_str());
+ ++i;
+ }
+}
+
+static void PrintSectionContents(const ObjectFile *o) {
+ error_code ec;
+ for (section_iterator si = o->begin_sections(),
+ se = o->end_sections();
+ si != se; si.increment(ec)) {
+ if (error(ec)) return;
+ StringRef Name;
+ StringRef Contents;
+ uint64_t BaseAddr;
+ bool BSS;
+ if (error(si->getName(Name))) continue;
+ if (error(si->getContents(Contents))) continue;
+ if (error(si->getAddress(BaseAddr))) continue;
+ if (error(si->isBSS(BSS))) continue;
+
+ outs() << "Contents of section " << Name << ":\n";
+ if (BSS) {
+ outs() << format("<skipping contents of bss section at [%04" PRIx64
+ ", %04" PRIx64 ")>\n", BaseAddr,
+ BaseAddr + Contents.size());
+ continue;
+ }
+
+ // Dump out the content as hex and printable ascii characters.
+ for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) {
+ outs() << format(" %04" PRIx64 " ", BaseAddr + addr);
+ // Dump line of hex.
+ for (std::size_t i = 0; i < 16; ++i) {
+ if (i != 0 && i % 4 == 0)
+ outs() << ' ';
+ if (addr + i < end)
+ outs() << hexdigit((Contents[addr + i] >> 4) & 0xF, true)
+ << hexdigit(Contents[addr + i] & 0xF, true);
+ else
+ outs() << " ";
+ }
+ // Print ascii.
+ outs() << " ";
+ for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
+ if (std::isprint(static_cast<unsigned char>(Contents[addr + i]) & 0xFF))
+ outs() << Contents[addr + i];
+ else
+ outs() << ".";
+ }
+ outs() << "\n";
+ }
+ }
+}
+
+static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
+ const coff_file_header *header;
+ if (error(coff->getHeader(header))) return;
+ int aux_count = 0;
+ const coff_symbol *symbol = 0;
+ for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) {
+ if (aux_count--) {
+ // Figure out which type of aux this is.
+ if (symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC
+ && symbol->Value == 0) { // Section definition.
+ const coff_aux_section_definition *asd;
+ if (error(coff->getAuxSymbol<coff_aux_section_definition>(i, asd)))
+ return;
+ outs() << "AUX "
+ << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x "
+ , unsigned(asd->Length)
+ , unsigned(asd->NumberOfRelocations)
+ , unsigned(asd->NumberOfLinenumbers)
+ , unsigned(asd->CheckSum))
+ << format("assoc %d comdat %d\n"
+ , unsigned(asd->Number)
+ , unsigned(asd->Selection));
+ } else
+ outs() << "AUX Unknown\n";
+ } else {
+ StringRef name;
+ if (error(coff->getSymbol(i, symbol))) return;
+ if (error(coff->getSymbolName(symbol, name))) return;
+ outs() << "[" << format("%2d", i) << "]"
+ << "(sec " << format("%2d", int(symbol->SectionNumber)) << ")"
+ << "(fl 0x00)" // Flag bits, which COFF doesn't have.
+ << "(ty " << format("%3x", unsigned(symbol->Type)) << ")"
+ << "(scl " << format("%3x", unsigned(symbol->StorageClass)) << ") "
+ << "(nx " << unsigned(symbol->NumberOfAuxSymbols) << ") "
+ << "0x" << format("%08x", unsigned(symbol->Value)) << " "
+ << name << "\n";
+ aux_count = symbol->NumberOfAuxSymbols;
+ }
+ }
+}