| ... | @@ -950,6 +950,8 @@ const ElfDumper = struct { | ... | @@ -950,6 +950,8 @@ const ElfDumper = struct { |
| 950 | fn dumpShdrs(ctx: Context, writer: anytype) !void { | 950 | fn dumpShdrs(ctx: Context, writer: anytype) !void { |
| 951 | if (ctx.shdrs.len == 0) return; | 951 | if (ctx.shdrs.len == 0) return; |
| 952 | | 952 | |
| | 953 | try writer.writeAll("section headers\n"); |
| | 954 | |
| 953 | for (ctx.shdrs, 0..) |shdr, shndx| { | 955 | for (ctx.shdrs, 0..) |shdr, shndx| { |
| 954 | try writer.print("shdr {d}\n", .{shndx}); | 956 | try writer.print("shdr {d}\n", .{shndx}); |
| 955 | try writer.print("name {s}\n", .{getSectionName(ctx, shndx)}); | 957 | try writer.print("name {s}\n", .{getSectionName(ctx, shndx)}); |
| ... | @@ -1113,46 +1115,46 @@ const ElfDumper = struct { | ... | @@ -1113,46 +1115,46 @@ const ElfDumper = struct { |
| 1113 | ) !void { | 1115 | ) !void { |
| 1114 | _ = unused_fmt_string; | 1116 | _ = unused_fmt_string; |
| 1115 | _ = options; | 1117 | _ = options; |
| 1116 | if (elf.SHT_LOOS <= sh_type and sh_type < elf.SHT_HIOS) { | 1118 | const name = switch (sh_type) { |
| 1117 | try writer.print("LOOS+0x{x}", .{sh_type - elf.SHT_LOOS}); | 1119 | elf.SHT_NULL => "NULL", |
| 1118 | } else if (elf.SHT_LOPROC <= sh_type and sh_type < elf.SHT_HIPROC) { | 1120 | elf.SHT_PROGBITS => "PROGBITS", |
| 1119 | try writer.print("LOPROC+0x{x}", .{sh_type - elf.SHT_LOPROC}); | 1121 | elf.SHT_SYMTAB => "SYMTAB", |
| 1120 | } else if (elf.SHT_LOUSER <= sh_type and sh_type < elf.SHT_HIUSER) { | 1122 | elf.SHT_STRTAB => "STRTAB", |
| 1121 | try writer.print("LOUSER+0x{x}", .{sh_type - elf.SHT_LOUSER}); | 1123 | elf.SHT_RELA => "RELA", |
| 1122 | } else { | 1124 | elf.SHT_HASH => "HASH", |
| 1123 | const name = switch (sh_type) { | 1125 | elf.SHT_DYNAMIC => "DYNAMIC", |
| 1124 | elf.SHT_NULL => "NULL", | 1126 | elf.SHT_NOTE => "NOTE", |
| 1125 | elf.SHT_PROGBITS => "PROGBITS", | 1127 | elf.SHT_NOBITS => "NOBITS", |
| 1126 | elf.SHT_SYMTAB => "SYMTAB", | 1128 | elf.SHT_REL => "REL", |
| 1127 | elf.SHT_STRTAB => "STRTAB", | 1129 | elf.SHT_SHLIB => "SHLIB", |
| 1128 | elf.SHT_RELA => "RELA", | 1130 | elf.SHT_DYNSYM => "DYNSYM", |
| 1129 | elf.SHT_HASH => "HASH", | 1131 | elf.SHT_INIT_ARRAY => "INIT_ARRAY", |
| 1130 | elf.SHT_DYNAMIC => "DYNAMIC", | 1132 | elf.SHT_FINI_ARRAY => "FINI_ARRAY", |
| 1131 | elf.SHT_NOTE => "NOTE", | 1133 | elf.SHT_PREINIT_ARRAY => "PREINIT_ARRAY", |
| 1132 | elf.SHT_NOBITS => "NOBITS", | 1134 | elf.SHT_GROUP => "GROUP", |
| 1133 | elf.SHT_REL => "REL", | 1135 | elf.SHT_SYMTAB_SHNDX => "SYMTAB_SHNDX", |
| 1134 | elf.SHT_SHLIB => "SHLIB", | 1136 | elf.SHT_X86_64_UNWIND => "X86_64_UNWIND", |
| 1135 | elf.SHT_DYNSYM => "DYNSYM", | 1137 | elf.SHT_LLVM_ADDRSIG => "LLVM_ADDRSIG", |
| 1136 | elf.SHT_INIT_ARRAY => "INIT_ARRAY", | 1138 | elf.SHT_GNU_HASH => "GNU_HASH", |
| 1137 | elf.SHT_FINI_ARRAY => "FINI_ARRAY", | 1139 | elf.SHT_GNU_VERDEF => "VERDEF", |
| 1138 | elf.SHT_PREINIT_ARRAY => "PREINIT_ARRAY", | 1140 | elf.SHT_GNU_VERNEED => "VERNEED", |
| 1139 | elf.SHT_GROUP => "GROUP", | 1141 | elf.SHT_GNU_VERSYM => "VERSYM", |
| 1140 | elf.SHT_SYMTAB_SHNDX => "SYMTAB_SHNDX", | 1142 | else => if (elf.SHT_LOOS <= sh_type and sh_type < elf.SHT_HIOS) { |
| 1141 | elf.SHT_X86_64_UNWIND => "X86_64_UNWIND", | 1143 | return try writer.print("LOOS+0x{x}", .{sh_type - elf.SHT_LOOS}); |
| 1142 | elf.SHT_LLVM_ADDRSIG => "LLVM_ADDRSIG", | 1144 | } else if (elf.SHT_LOPROC <= sh_type and sh_type < elf.SHT_HIPROC) { |
| 1143 | elf.SHT_GNU_HASH => "GNU_HASH", | 1145 | return try writer.print("LOPROC+0x{x}", .{sh_type - elf.SHT_LOPROC}); |
| 1144 | elf.SHT_GNU_VERDEF => "VERDEF", | 1146 | } else if (elf.SHT_LOUSER <= sh_type and sh_type < elf.SHT_HIUSER) { |
| 1145 | elf.SHT_GNU_VERNEED => "VERNEED", | 1147 | return try writer.print("LOUSER+0x{x}", .{sh_type - elf.SHT_LOUSER}); |
| 1146 | elf.SHT_GNU_VERSYM => "VERSYM", | 1148 | } else "UNKNOWN", |
| 1147 | else => "UNKNOWN", | 1149 | }; |
| 1148 | }; | 1150 | try writer.writeAll(name); |
| 1149 | try writer.writeAll(name); | | |
| 1150 | } | | |
| 1151 | } | 1151 | } |
| 1152 | | 1152 | |
| 1153 | fn dumpPhdrs(ctx: Context, writer: anytype) !void { | 1153 | fn dumpPhdrs(ctx: Context, writer: anytype) !void { |
| 1154 | if (ctx.phdrs.len == 0) return; | 1154 | if (ctx.phdrs.len == 0) return; |
| 1155 | | 1155 | |
| | 1156 | try writer.writeAll("program headers\n"); |
| | 1157 | |
| 1156 | for (ctx.phdrs, 0..) |phdr, phndx| { | 1158 | for (ctx.phdrs, 0..) |phdr, phndx| { |
| 1157 | try writer.print("phdr {d}\n", .{phndx}); | 1159 | try writer.print("phdr {d}\n", .{phndx}); |
| 1158 | try writer.print("type {s}\n", .{fmtPhType(phdr.p_type)}); | 1160 | try writer.print("type {s}\n", .{fmtPhType(phdr.p_type)}); |
| ... | @@ -1162,7 +1164,28 @@ const ElfDumper = struct { | ... | @@ -1162,7 +1164,28 @@ const ElfDumper = struct { |
| 1162 | try writer.print("memsz {x}\n", .{phdr.p_memsz}); | 1164 | try writer.print("memsz {x}\n", .{phdr.p_memsz}); |
| 1163 | try writer.print("filesz {x}\n", .{phdr.p_filesz}); | 1165 | try writer.print("filesz {x}\n", .{phdr.p_filesz}); |
| 1164 | try writer.print("align {x}\n", .{phdr.p_align}); | 1166 | try writer.print("align {x}\n", .{phdr.p_align}); |
| 1165 | // TODO dump formatted p_flags | 1167 | |
| | 1168 | { |
| | 1169 | const flags = phdr.p_flags; |
| | 1170 | try writer.writeAll("flags"); |
| | 1171 | if (flags > 0) try writer.writeByte(' '); |
| | 1172 | if (flags & elf.PF_R != 0) { |
| | 1173 | try writer.writeByte('R'); |
| | 1174 | } |
| | 1175 | if (flags & elf.PF_W != 0) { |
| | 1176 | try writer.writeByte('W'); |
| | 1177 | } |
| | 1178 | if (flags & elf.PF_X != 0) { |
| | 1179 | try writer.writeByte('E'); |
| | 1180 | } |
| | 1181 | if (flags & elf.PF_MASKOS != 0) { |
| | 1182 | try writer.writeAll("OS"); |
| | 1183 | } |
| | 1184 | if (flags & elf.PF_MASKPROC != 0) { |
| | 1185 | try writer.writeAll("PROC"); |
| | 1186 | } |
| | 1187 | try writer.writeByte('\n'); |
| | 1188 | } |
| 1166 | } | 1189 | } |
| 1167 | } | 1190 | } |
| 1168 | | 1191 | |
| ... | @@ -1178,28 +1201,26 @@ const ElfDumper = struct { | ... | @@ -1178,28 +1201,26 @@ const ElfDumper = struct { |
| 1178 | ) !void { | 1201 | ) !void { |
| 1179 | _ = unused_fmt_string; | 1202 | _ = unused_fmt_string; |
| 1180 | _ = options; | 1203 | _ = options; |
| 1181 | if (elf.PT_LOOS <= ph_type and ph_type < elf.PT_HIOS) { | 1204 | const p_type = switch (ph_type) { |
| 1182 | try writer.print("LOOS+0x{x}", .{ph_type - elf.PT_LOOS}); | 1205 | elf.PT_NULL => "NULL", |
| 1183 | } else if (elf.PT_LOPROC <= ph_type and ph_type < elf.PT_HIPROC) { | 1206 | elf.PT_LOAD => "LOAD", |
| 1184 | try writer.print("LOPROC+0x{x}", .{ph_type - elf.PT_LOPROC}); | 1207 | elf.PT_DYNAMIC => "DYNAMIC", |
| 1185 | } else { | 1208 | elf.PT_INTERP => "INTERP", |
| 1186 | const p_type = switch (ph_type) { | 1209 | elf.PT_NOTE => "NOTE", |
| 1187 | elf.PT_NULL => "NULL", | 1210 | elf.PT_SHLIB => "SHLIB", |
| 1188 | elf.PT_LOAD => "LOAD", | 1211 | elf.PT_PHDR => "PHDR", |
| 1189 | elf.PT_DYNAMIC => "DYNAMIC", | 1212 | elf.PT_TLS => "TLS", |
| 1190 | elf.PT_INTERP => "INTERP", | 1213 | elf.PT_NUM => "NUM", |
| 1191 | elf.PT_NOTE => "NOTE", | 1214 | elf.PT_GNU_EH_FRAME => "GNU_EH_FRAME", |
| 1192 | elf.PT_SHLIB => "SHLIB", | 1215 | elf.PT_GNU_STACK => "GNU_STACK", |
| 1193 | elf.PT_PHDR => "PHDR", | 1216 | elf.PT_GNU_RELRO => "GNU_RELRO", |
| 1194 | elf.PT_TLS => "TLS", | 1217 | else => if (elf.PT_LOOS <= ph_type and ph_type < elf.PT_HIOS) { |
| 1195 | elf.PT_NUM => "NUM", | 1218 | return try writer.print("LOOS+0x{x}", .{ph_type - elf.PT_LOOS}); |
| 1196 | elf.PT_GNU_EH_FRAME => "GNU_EH_FRAME", | 1219 | } else if (elf.PT_LOPROC <= ph_type and ph_type < elf.PT_HIPROC) { |
| 1197 | elf.PT_GNU_STACK => "GNU_STACK", | 1220 | return try writer.print("LOPROC+0x{x}", .{ph_type - elf.PT_LOPROC}); |
| 1198 | elf.PT_GNU_RELRO => "GNU_RELRO", | 1221 | } else "UNKNOWN", |
| 1199 | else => "UNKNOWN", | 1222 | }; |
| 1200 | }; | 1223 | try writer.writeAll(p_type); |
| 1201 | try writer.writeAll(p_type); | | |
| 1202 | } | | |
| 1203 | } | 1224 | } |
| 1204 | | 1225 | |
| 1205 | fn dumpSymtab(ctx: Context, comptime @"type": enum { symtab, dysymtab }, writer: anytype) !void { | 1226 | fn dumpSymtab(ctx: Context, comptime @"type": enum { symtab, dysymtab }, writer: anytype) !void { |