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