summaryrefslogtreecommitdiff
path: root/Userland/Utilities/readelf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Utilities/readelf.cpp')
-rw-r--r--Userland/Utilities/readelf.cpp267
1 files changed, 134 insertions, 133 deletions
diff --git a/Userland/Utilities/readelf.cpp b/Userland/Utilities/readelf.cpp
index 4f5fddea3d..a95ad827e7 100644
--- a/Userland/Utilities/readelf.cpp
+++ b/Userland/Utilities/readelf.cpp
@@ -413,14 +413,14 @@ int main(int argc, char** argv)
ELF::Image elf_image(elf_image_data);
if (!elf_image.is_valid()) {
- fprintf(stderr, "File is not a valid ELF object\n");
+ warnln("File is not a valid ELF object");
return -1;
}
String interpreter_path;
if (!ELF::validate_program_headers(*(const Elf32_Ehdr*)elf_image_data.data(), elf_image_data.size(), (const u8*)elf_image_data.data(), elf_image_data.size(), &interpreter_path)) {
- fprintf(stderr, "Invalid ELF headers\n");
+ warnln("Invalid ELF headers");
return -1;
}
@@ -431,7 +431,7 @@ int main(int argc, char** argv)
if (elf_image.is_dynamic()) {
if (interpreter_path.is_null()) {
interpreter_path = "/usr/lib/Loader.so";
- fprintf(stderr, "Warning: Dynamic ELF object has no interpreter path. Using: %s\n", interpreter_path.characters());
+ warnln("Warning: Dynamic ELF object has no interpreter path. Using: {}", interpreter_path);
}
auto interpreter_file_or_error = MappedFile::map(interpreter_path);
@@ -446,7 +446,7 @@ int main(int argc, char** argv)
ELF::Image interpreter_image(interpreter_image_data);
if (!interpreter_image.is_valid()) {
- fprintf(stderr, "ELF interpreter image is invalid\n");
+ warnln("ELF interpreter image is invalid");
return -1;
}
@@ -475,91 +475,92 @@ int main(int argc, char** argv)
}
if (display_elf_header) {
- printf("ELF header:\n");
+ outln("ELF header:");
- printf(" Magic: ");
+ out(" Magic: ");
for (char i : StringView { header.e_ident, sizeof(header.e_ident) }) {
if (isprint(i)) {
- printf("%c ", i);
+ out("{:c} ", i);
} else {
- printf("%02x ", i);
+ out("{:02x} ", i);
}
}
- printf("\n");
-
- printf(" Type: %d (%s)\n", header.e_type, object_file_type_to_string(header.e_type));
- printf(" Machine: %u (%s)\n", header.e_machine, object_machine_type_to_string(header.e_machine));
- printf(" Version: 0x%x\n", header.e_version);
- printf(" Entry point address: 0x%x\n", header.e_entry);
- printf(" Start of program headers: %u (bytes into file)\n", header.e_phoff);
- printf(" Start of section headers: %u (bytes into file)\n", header.e_shoff);
- printf(" Flags: 0x%x\n", header.e_flags);
- printf(" Size of this header: %u (bytes)\n", header.e_ehsize);
- printf(" Size of program headers: %u (bytes)\n", header.e_phentsize);
- printf(" Number of program headers: %u\n", header.e_phnum);
- printf(" Size of section headers: %u (bytes)\n", header.e_shentsize);
- printf(" Number of section headers: %u\n", header.e_shnum);
- printf(" Section header string table index: %u\n", header.e_shstrndx);
- printf("\n");
+ outln();
+
+ outln(" Type: {} ({})", header.e_type, object_file_type_to_string(header.e_type));
+ outln(" Machine: {} ({})", header.e_machine, object_machine_type_to_string(header.e_machine));
+ outln(" Version: {:#x}", header.e_version);
+ outln(" Entry point address: {:#x}", header.e_entry);
+ outln(" Start of program headers: {} (bytes into file)", header.e_phoff);
+ outln(" Start of section headers: {} (bytes into file)", header.e_shoff);
+ outln(" Flags: {:#x}", header.e_flags);
+ outln(" Size of this header: {} (bytes)", header.e_ehsize);
+ outln(" Size of program headers: {} (bytes)", header.e_phentsize);
+ outln(" Number of program headers: {}", header.e_phnum);
+ outln(" Size of section headers: {} (bytes)", header.e_shentsize);
+ outln(" Number of section headers: {}", header.e_shnum);
+ outln(" Section header string table index: {}", header.e_shstrndx);
+ outln();
}
if (display_section_headers) {
if (!display_all) {
- printf("There are %u section headers, starting at offset 0x%x:\n", header.e_shnum, header.e_shoff);
- printf("\n");
+ outln("There are {} section headers, starting at offset {:#x}:", header.e_shnum, header.e_shoff);
+ outln();
}
if (!elf_image.section_count()) {
- printf("There are no sections in this file.\n");
+ outln("There are no sections in this file.");
} else {
- printf("Section Headers:\n");
- printf(" Name Type Address Offset Size Flags\n");
+ outln("Section Headers:");
+ outln(" Name Type Address Offset Size Flags");
elf_image.for_each_section([](const ELF::Image::Section& section) {
- printf(" %-19s ", StringView(section.name()).to_string().characters());
- printf("%-15s ", object_section_header_type_to_string(section.type()));
- printf("%08x ", section.address());
- printf("%08x ", section.offset());
- printf("%08x ", section.size());
- printf("%u", section.flags());
- printf("\n");
+ out(" {:19} ", section.name());
+ out("{:15} ", object_section_header_type_to_string(section.type()));
+ out("{:08x} ", section.address());
+ out("{:08x} ", section.offset());
+ out("{:08x} ", section.size());
+ out("{}", section.flags());
+ outln();
});
}
- printf("\n");
+ outln();
}
if (display_program_headers) {
if (!display_all) {
- printf("Elf file type is %d (%s)\n", header.e_type, object_file_type_to_string(header.e_type));
- printf("Entry point 0x%x\n", header.e_entry);
- printf("There are %u program headers, starting at offset %u\n", header.e_phnum, header.e_phoff);
- printf("\n");
+ outln("ELF file type is {} ({})", header.e_type, object_file_type_to_string(header.e_type));
+ outln("Entry point {:#x}\n", header.e_entry);
+ outln("There are {} program headers, starting at offset {}", header.e_phnum, header.e_phoff);
+ outln();
}
if (!elf_image.program_header_count()) {
- printf("There are no program headers in this file.\n");
+ outln("There are no program headers in this file.");
} else {
- printf("Program Headers:\n");
- printf(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n");
+ outln("Program Headers:");
+ outln(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align");
elf_image.for_each_program_header([](const ELF::Image::ProgramHeader& program_header) {
- printf(" %-14s ", object_program_header_type_to_string(program_header.type()));
- printf("0x%08x ", program_header.offset());
- printf("%p ", program_header.vaddr().as_ptr());
- printf("%p ", program_header.vaddr().as_ptr()); // FIXME: assumes PhysAddr = VirtAddr
- printf("0x%08x ", program_header.size_in_image());
- printf("0x%08x ", program_header.size_in_memory());
- printf("%04x ", program_header.flags());
- printf("0x%08x", program_header.alignment());
- printf("\n");
+ out(" ");
+ out("{:14} ", object_program_header_type_to_string(program_header.type()));
+ out("{:#08x} ", program_header.offset());
+ out("{:p} ", program_header.vaddr().as_ptr());
+ out("{:p} ", program_header.vaddr().as_ptr()); // FIXME: assumes PhysAddr = VirtAddr
+ out("{:#08x} ", program_header.size_in_image());
+ out("{:#08x} ", program_header.size_in_memory());
+ out("{:04x} ", program_header.flags());
+ out("{:#08x}", program_header.alignment());
+ outln();
if (program_header.type() == PT_INTERP)
- printf(" [Interpreter: %s]\n", program_header.raw_data());
+ outln(" [Interpreter: {}]", program_header.raw_data());
});
}
// TODO: Display section to segment mapping
- printf("\n");
+ outln();
}
if (display_dynamic_section) {
@@ -572,9 +573,9 @@ int main(int argc, char** argv)
found_dynamic_section = true;
if (section.entry_count()) {
- printf("Dynamic section '%s' at offset 0x%08x contains %u entries.\n", section.name().to_string().characters(), section.offset(), section.entry_count());
+ outln("Dynamic section '{}' at offset {:#08x} contains {} entries.", section.name().to_string(), section.offset(), section.entry_count());
} else {
- printf("Dynamic section '%s' at offset 0x%08x contains zero entries.\n", section.name().to_string().characters(), section.offset());
+ outln("Dynamic section '{}' at offset {:#08x} contains zero entries.", section.name().to_string(), section.offset());
}
return IterationDecision::Break;
@@ -582,77 +583,77 @@ int main(int argc, char** argv)
Vector<String> libraries;
object->for_each_needed_library([&libraries](StringView entry) {
- libraries.append(String::formatted("{}", entry).characters());
+ libraries.append(String::formatted("{}", entry));
});
auto library_index = 0;
- printf(" Tag Type Name / Value\n");
+ outln(" Tag Type Name / Value");
object->for_each_dynamic_entry([&library_index, &libraries, &object](const ELF::DynamicObject::DynamicEntry& entry) {
- printf(" 0x%08x ", entry.tag());
- printf("%-17s ", object_tag_to_string(entry.tag()));
+ out(" {:#08x} ", entry.tag());
+ out("{:17} ", object_tag_to_string(entry.tag()));
if (entry.tag() == DT_NEEDED) {
- printf("Shared library: %s\n", String(libraries[library_index]).characters());
+ outln("Shared library: {}", libraries[library_index]);
library_index++;
} else if (entry.tag() == DT_RPATH) {
- printf("Library rpath: %s\n", String(object->rpath()).characters());
+ outln("Library rpath: {}", object->rpath());
} else if (entry.tag() == DT_RUNPATH) {
- printf("Library runpath: %s\n", String(object->runpath()).characters());
+ outln("Library runpath: {}", object->runpath());
} else if (entry.tag() == DT_SONAME) {
- printf("Library soname: %s\n", String(object->soname()).characters());
+ outln("Library soname: {}", object->soname());
} else {
- printf("0x%08x\n", entry.val());
+ outln("{:#08x}", entry.val());
}
});
}
if (!found_dynamic_section)
- printf("No dynamic section in this file.\n");
+ outln("No dynamic section in this file.");
- printf("\n");
+ outln();
}
if (display_relocations) {
if (elf_image.is_dynamic()) {
if (!object->relocation_section().entry_count()) {
- printf("Relocation section '%s' at offset 0x%08x contains zero entries:\n", object->relocation_section().name().to_string().characters(), object->relocation_section().offset());
+ outln("Relocation section '{}' at offset {:#08x} contains zero entries:", object->relocation_section().name(), object->relocation_section().offset());
} else {
- printf("Relocation section '%s' at offset 0x%08x contains %u entries:\n", object->relocation_section().name().to_string().characters(), object->relocation_section().offset(), object->relocation_section().entry_count());
- printf(" Offset Type Sym Value Sym Name\n");
+ outln("Relocation section '{}' at offset {:#08x} contains {} entries:", object->relocation_section().name(), object->relocation_section().offset(), object->relocation_section().entry_count());
+ outln(" Offset Type Sym Value Sym Name");
object->relocation_section().for_each_relocation([](const ELF::DynamicObject::Relocation& reloc) {
- printf(" 0x%08x ", reloc.offset());
- printf(" %-17s ", object_relocation_type_to_string(reloc.type()));
- printf(" 0x%08x ", reloc.symbol().value());
- printf(" %s", reloc.symbol().name().to_string().characters());
- printf("\n");
+ out(" {:#08x} ", reloc.offset());
+ out(" {:17} ", object_relocation_type_to_string(reloc.type()));
+ out(" {:#08x} ", reloc.symbol().value());
+ out(" {}", reloc.symbol().name());
+ outln();
});
}
- printf("\n");
+ outln();
if (!object->plt_relocation_section().entry_count()) {
- printf("Relocation section '%s' at offset 0x%08x contains zero entries:\n", object->plt_relocation_section().name().to_string().characters(), object->plt_relocation_section().offset());
+ outln("Relocation section '{}' at offset {:#08x} contains zero entries:", object->plt_relocation_section().name(), object->plt_relocation_section().offset());
} else {
- printf("Relocation section '%s' at offset 0x%08x contains %u entries:\n", object->plt_relocation_section().name().to_string().characters(), object->plt_relocation_section().offset(), object->plt_relocation_section().entry_count());
- printf(" Offset Type Sym Value Sym Name\n");
+ outln("Relocation section '{}' at offset {:#08x} contains {} entries:", object->plt_relocation_section().name(), object->plt_relocation_section().offset(), object->plt_relocation_section().entry_count());
+ outln(" Offset Type Sym Value Sym Name");
object->plt_relocation_section().for_each_relocation([](const ELF::DynamicObject::Relocation& reloc) {
- printf(" 0x%08x ", reloc.offset());
- printf(" %-17s ", object_relocation_type_to_string(reloc.type()));
- printf(" 0x%08x ", reloc.symbol().value());
- printf(" %s", reloc.symbol().name().to_string().characters());
- printf("\n");
+ out(" {:#08x} ", reloc.offset());
+ out(" {:17} ", object_relocation_type_to_string(reloc.type()));
+ out(" {:#08x} ", reloc.symbol().value());
+ out(" {}", reloc.symbol().name());
+ outln();
});
}
} else {
- printf("No relocations in this file.\n");
+ outln("No relocations in this file.");
}
- printf("\n");
+ outln();
}
if (display_unwind_info) {
// TODO: Unwind info
- printf("Decoding of unwind sections for machine type %s is not supported.\n", object_machine_type_to_string(header.e_machine));
- printf("\n");
+ outln("Decoding of unwind sections for machine type {} is not supported.", object_machine_type_to_string(header.e_machine));
+ outln();
}
if (display_core_notes) {
@@ -663,16 +664,16 @@ int main(int argc, char** argv)
found_notes = true;
- printf("Displaying notes section '%s' at offset 0x%08x of length 0x%08x:\n", object_program_header_type_to_string(program_header.type()), program_header.offset(), program_header.size_in_image());
+ outln("Displaying notes section '{}' at offset {:#08x} of length {:#08x}:", object_program_header_type_to_string(program_header.type()), program_header.offset(), program_header.size_in_image());
// FIXME: Parse CORE notes. Notes are in JSON format on SerenityOS, but vary between systems.
- printf("%s\n", program_header.raw_data());
+ outln("{}", program_header.raw_data());
});
if (!found_notes)
- printf("No core notes in this file.\n");
+ outln("No core notes in this file.");
- printf("\n");
+ outln();
}
if (display_dynamic_symbol_table || display_symbol_table) {
@@ -686,9 +687,9 @@ int main(int argc, char** argv)
found_dynamic_symbol_table = true;
if (!section.entry_count()) {
- printf("Symbol table '%s' contains zero entries.\n", ELF_DYNSYM);
+ outln("Symbol table '{}' contains zero entries.", ELF_DYNSYM);
} else {
- printf("Symbol table '%s' contains %u entries.\n", ELF_DYNSYM, section.entry_count());
+ outln("Symbol table '{}' contains {} entries.", ELF_DYNSYM, section.entry_count());
}
return IterationDecision::Break;
@@ -696,48 +697,48 @@ int main(int argc, char** argv)
if (object->symbol_count()) {
// FIXME: Add support for init/fini/start/main sections
- printf(" Num: Value Size Type Bind Name\n");
+ outln(" Num: Value Size Type Bind Name");
object->for_each_symbol([](const ELF::DynamicObject::Symbol& sym) {
- printf(" %4u: ", sym.index());
- printf("%08x ", sym.value());
- printf("%08x ", sym.size());
- printf("%-8s ", object_symbol_type_to_string(sym.type()));
- printf("%-8s ", object_symbol_binding_to_string(sym.bind()));
- printf("%s", StringView(sym.name()).to_string().characters());
- printf("\n");
+ out(" {:>4}: ", sym.index());
+ out("{:08x} ", sym.value());
+ out("{:08x} ", sym.size());
+ out("{:8} ", object_symbol_type_to_string(sym.type()));
+ out("{:8} ", object_symbol_binding_to_string(sym.bind()));
+ out("{}", sym.name());
+ outln();
});
}
}
if (!found_dynamic_symbol_table)
- printf("No dynamic symbol information for this file.\n");
+ outln("No dynamic symbol information for this file.");
- printf("\n");
+ outln();
}
if (display_symbol_table) {
if (elf_image.symbol_count()) {
- printf("Symbol table '%s' contains %u entries:\n", ELF_SYMTAB, elf_image.symbol_count());
- printf(" Num: Value Size Type Bind Name\n");
+ outln("Symbol table '{}' contains {} entries:", ELF_SYMTAB, elf_image.symbol_count());
+ outln(" Num: Value Size Type Bind Name");
elf_image.for_each_symbol([](const ELF::Image::Symbol& sym) {
- printf(" %4u: ", sym.index());
- printf("%08x ", sym.value());
- printf("%08x ", sym.size());
- printf("%-8s ", object_symbol_type_to_string(sym.type()));
- printf("%-8s ", object_symbol_binding_to_string(sym.bind()));
- printf("%s", StringView(sym.name()).to_string().characters());
- printf("\n");
+ out(" {:>4}: ", sym.index());
+ out("{:08x} ", sym.value());
+ out("{:08x} ", sym.size());
+ out("{:8} ", object_symbol_type_to_string(sym.type()));
+ out("{:8} ", object_symbol_binding_to_string(sym.bind()));
+ out("{}", sym.name());
+ outln();
});
} else {
- printf("Symbol table '%s' contains zero entries.\n", ELF_SYMTAB);
+ outln("Symbol table '{}' contains zero entries.", ELF_SYMTAB);
}
- printf("\n");
+ outln();
}
if (display_hardening) {
- printf("Security Hardening:\n");
- printf("RELRO Stack Canary NX PIE RPATH RUNPATH Symbols \n");
+ outln("Security Hardening:");
+ outln("RELRO Stack Canary NX PIE RPATH RUNPATH Symbols ");
bool relro = false;
elf_image.for_each_program_header([&relro](const ELF::Image::ProgramHeader& program_header) {
@@ -758,11 +759,11 @@ int main(int argc, char** argv)
return IterationDecision::Continue;
});
if (full_relro)
- printf("\033[0;32m%-13s\033[0m ", "Full RELRO");
+ out("\033[0;32m{:13}\033[0m ", "Full RELRO");
else
- printf("\033[0;33m%-13s\033[0m ", "Partial RELRO");
+ out("\033[0;33m{:13}\033[0m ", "Partial RELRO");
} else {
- printf("\033[0;31m%-13s\033[0m ", "No RELRO");
+ out("\033[0;31m{:13}\033[0m ", "No RELRO");
}
bool canary = false;
@@ -775,9 +776,9 @@ int main(int argc, char** argv)
});
if (canary)
- printf("\033[0;32m%-12s\033[0m ", "Canary found");
+ out("\033[0;32m{:12}\033[0m ", "Canary found");
else
- printf("\033[0;31m%-12s\033[0m ", "No canary");
+ out("\033[0;31m{:12}\033[0m ", "No canary");
bool nx = false;
elf_image.for_each_program_header([&nx](const ELF::Image::ProgramHeader& program_header) {
@@ -792,39 +793,39 @@ int main(int argc, char** argv)
});
if (nx)
- printf("\033[0;32m%-12s\033[0m ", "NX enabled");
+ out("\033[0;32m{:12}\033[0m ", "NX enabled");
else
- printf("\033[0;31m%-12s\033[0m ", "NX disabled");
+ out("\033[0;31m{:12}\033[0m ", "NX disabled");
bool pie = false;
if (header.e_type == ET_REL || header.e_type == ET_DYN)
pie = true;
if (pie)
- printf("\033[0;32m%-12s\033[0m ", "PIE enabled");
+ out("\033[0;32m{:12}\033[0m ", "PIE enabled");
else
- printf("\033[0;31m%-12s\033[0m ", "No PIE");
+ out("\033[0;31m{:12}\033[0m ", "No PIE");
StringView rpath;
if (elf_image.is_dynamic())
rpath = object->rpath();
if (rpath.is_empty())
- printf("\033[0;32m%-12s\033[0m ", "No RPATH");
+ out("\033[0;32m{:12}\033[0m ", "No RPATH");
else
- printf("\033[0;31m%-12s\033[0m ", rpath.to_string().characters());
+ out("\033[0;31m{:12}\033[0m ", rpath);
StringView runpath;
if (elf_image.is_dynamic())
runpath = object->runpath();
if (runpath.is_empty())
- printf("\033[0;32m%-12s\033[0m ", "No RUNPATH");
+ out("\033[0;32m{:12}\033[0m ", "No RUNPATH");
else
- printf("\033[0;31m%-12s\033[0m ", runpath.to_string().characters());
+ out("\033[0;31m{:12}\033[0m ", runpath);
- printf("%u symbols ", elf_image.symbol_count());
- printf("\n");
+ out("{} symbols", elf_image.symbol_count());
+ outln();
}
return 0;