| ... | @@ -15,9 +15,12 @@ const MachO = @import("../MachO.zig"); | ... | @@ -15,9 +15,12 @@ const MachO = @import("../MachO.zig"); |
| 15 | const satMul = MachO.satMul; | 15 | const satMul = MachO.satMul; |
| 16 | const alloc_num = MachO.alloc_num; | 16 | const alloc_num = MachO.alloc_num; |
| 17 | const alloc_den = MachO.alloc_den; | 17 | const alloc_den = MachO.alloc_den; |
| | 18 | const makeStaticString = MachO.makeStaticString; |
| 18 | | 19 | |
| 19 | usingnamespace @import("commands.zig"); | 20 | usingnamespace @import("commands.zig"); |
| 20 | | 21 | |
| | 22 | const page_size: u16 = 0x1000; |
| | 23 | |
| 21 | base: *MachO, | 24 | base: *MachO, |
| 22 | file: fs.File, | 25 | file: fs.File, |
| 23 | | 26 | |
| ... | @@ -44,12 +47,25 @@ uuid_cmd_index: ?u16 = null, | ... | @@ -44,12 +47,25 @@ uuid_cmd_index: ?u16 = null, |
| 44 | /// Index into __TEXT,__text section. | 47 | /// Index into __TEXT,__text section. |
| 45 | text_section_index: ?u16 = null, | 48 | text_section_index: ?u16 = null, |
| 46 | | 49 | |
| 47 | linkedit_off: u16 = 0x1000, | 50 | linkedit_off: u16 = page_size, |
| 48 | linkedit_size: u16 = 0x1000, | 51 | linkedit_size: u16 = page_size, |
| | 52 | |
| | 53 | debug_info_section_index: ?u16 = null, |
| | 54 | debug_abbrev_section_index: ?u16 = null, |
| | 55 | debug_str_section_index: ?u16 = null, |
| | 56 | debug_aranges_section_index: ?u16 = null, |
| | 57 | debug_line_section_index: ?u16 = null, |
| | 58 | |
| | 59 | debug_abbrev_table_offset: ?u64 = null, |
| 49 | | 60 | |
| 50 | header_dirty: bool = false, | 61 | header_dirty: bool = false, |
| 51 | load_commands_dirty: bool = false, | 62 | load_commands_dirty: bool = false, |
| 52 | string_table_dirty: bool = false, | 63 | string_table_dirty: bool = false, |
| | 64 | debug_string_table_dirty: bool = false, |
| | 65 | debug_abbrev_section_dirty: bool = false, |
| | 66 | debug_aranges_section_dirty: bool = false, |
| | 67 | debug_info_header_dirty: bool = false, |
| | 68 | debug_line_header_dirty: bool = false, |
| 53 | | 69 | |
| 54 | /// You must call this function *after* `MachO.populateMissingMetadata()` | 70 | /// You must call this function *after* `MachO.populateMissingMetadata()` |
| 55 | /// has been called to get a viable debug symbols output. | 71 | /// has been called to get a viable debug symbols output. |
| ... | @@ -98,7 +114,6 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void | ... | @@ -98,7 +114,6 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void |
| 98 | .strsize = base_cmd.strsize, | 114 | .strsize = base_cmd.strsize, |
| 99 | }, | 115 | }, |
| 100 | }); | 116 | }); |
| 101 | try self.writeLocalSymbol(0); | | |
| 102 | self.header_dirty = true; | 117 | self.header_dirty = true; |
| 103 | self.load_commands_dirty = true; | 118 | self.load_commands_dirty = true; |
| 104 | self.string_table_dirty = true; | 119 | self.string_table_dirty = true; |
| ... | @@ -139,6 +154,176 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void | ... | @@ -139,6 +154,176 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void |
| 139 | self.header_dirty = true; | 154 | self.header_dirty = true; |
| 140 | self.load_commands_dirty = true; | 155 | self.load_commands_dirty = true; |
| 141 | } | 156 | } |
| | 157 | if (self.dwarf_segment_cmd_index == null) { |
| | 158 | self.dwarf_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| | 159 | |
| | 160 | const linkedit = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| | 161 | const ideal_size: u16 = 200 + 128 + 160 + 250; |
| | 162 | const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, page_size); |
| | 163 | const off = linkedit.inner.fileoff + linkedit.inner.filesize; |
| | 164 | const vmaddr = linkedit.inner.vmaddr + linkedit.inner.vmsize; |
| | 165 | |
| | 166 | log.debug("found dSym __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size }); |
| | 167 | |
| | 168 | try self.load_commands.append(allocator, .{ |
| | 169 | .Segment = SegmentCommand.empty(.{ |
| | 170 | .cmd = macho.LC_SEGMENT_64, |
| | 171 | .cmdsize = @sizeOf(macho.segment_command_64), |
| | 172 | .segname = makeStaticString("__DWARF"), |
| | 173 | .vmaddr = vmaddr, |
| | 174 | .vmsize = needed_size, |
| | 175 | .fileoff = off, |
| | 176 | .filesize = needed_size, |
| | 177 | .maxprot = 0, |
| | 178 | .initprot = 0, |
| | 179 | .nsects = 0, |
| | 180 | .flags = 0, |
| | 181 | }), |
| | 182 | }); |
| | 183 | self.header_dirty = true; |
| | 184 | self.load_commands_dirty = true; |
| | 185 | } |
| | 186 | if (self.debug_str_section_index == null) { |
| | 187 | const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment; |
| | 188 | self.debug_str_section_index = @intCast(u16, dwarf_segment.sections.items.len); |
| | 189 | assert(self.base.debug_string_table.items.len == 0); |
| | 190 | |
| | 191 | const file_size_hint = 200; |
| | 192 | const p_align = 1; |
| | 193 | const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null); |
| | 194 | |
| | 195 | log.debug("found dSym __debug_strtab free space 0x{x} to 0x{x}", .{ off, off + file_size_hint }); |
| | 196 | |
| | 197 | try dwarf_segment.addSection(allocator, .{ |
| | 198 | .sectname = makeStaticString("__debug_str"), |
| | 199 | .segname = makeStaticString("__DWARF"), |
| | 200 | .addr = dwarf_segment.inner.vmaddr + off, |
| | 201 | .size = @intCast(u32, self.base.debug_string_table.items.len), |
| | 202 | .offset = @intCast(u32, off), |
| | 203 | .@"align" = 1, |
| | 204 | .reloff = 0, |
| | 205 | .nreloc = 0, |
| | 206 | .flags = macho.S_REGULAR, |
| | 207 | .reserved1 = 0, |
| | 208 | .reserved2 = 0, |
| | 209 | .reserved3 = 0, |
| | 210 | }); |
| | 211 | self.header_dirty = true; |
| | 212 | self.load_commands_dirty = true; |
| | 213 | self.debug_string_table_dirty = true; |
| | 214 | } |
| | 215 | if (self.debug_info_section_index == null) { |
| | 216 | const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment; |
| | 217 | self.debug_info_section_index = @intCast(u16, dwarf_segment.sections.items.len); |
| | 218 | |
| | 219 | const file_size_hint = 200; |
| | 220 | const p_align = 1; |
| | 221 | const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null); |
| | 222 | |
| | 223 | log.debug("found dSym __debug_info free space 0x{x} to 0x{x}", .{ off, off + file_size_hint }); |
| | 224 | |
| | 225 | try dwarf_segment.addSection(allocator, .{ |
| | 226 | .sectname = makeStaticString("__debug_info"), |
| | 227 | .segname = makeStaticString("__DWARF"), |
| | 228 | .addr = dwarf_segment.inner.vmaddr + off, |
| | 229 | .size = file_size_hint, |
| | 230 | .offset = @intCast(u32, off), |
| | 231 | .@"align" = p_align, |
| | 232 | .reloff = 0, |
| | 233 | .nreloc = 0, |
| | 234 | .flags = macho.S_REGULAR, |
| | 235 | .reserved1 = 0, |
| | 236 | .reserved2 = 0, |
| | 237 | .reserved3 = 0, |
| | 238 | }); |
| | 239 | self.header_dirty = true; |
| | 240 | self.load_commands_dirty = true; |
| | 241 | self.debug_info_header_dirty = true; |
| | 242 | } |
| | 243 | if (self.debug_abbrev_section_index == null) { |
| | 244 | const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment; |
| | 245 | self.debug_abbrev_section_index = @intCast(u16, dwarf_segment.sections.items.len); |
| | 246 | |
| | 247 | const file_size_hint = 128; |
| | 248 | const p_align = 1; |
| | 249 | const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null); |
| | 250 | |
| | 251 | log.debug("found dSym __debug_abbrev free space 0x{x} to 0x{x}", .{ off, off + file_size_hint }); |
| | 252 | |
| | 253 | try dwarf_segment.addSection(allocator, .{ |
| | 254 | .sectname = makeStaticString("__debug_abbrev"), |
| | 255 | .segname = makeStaticString("__DWARF"), |
| | 256 | .addr = dwarf_segment.inner.vmaddr + off, |
| | 257 | .size = file_size_hint, |
| | 258 | .offset = @intCast(u32, off), |
| | 259 | .@"align" = p_align, |
| | 260 | .reloff = 0, |
| | 261 | .nreloc = 0, |
| | 262 | .flags = macho.S_REGULAR, |
| | 263 | .reserved1 = 0, |
| | 264 | .reserved2 = 0, |
| | 265 | .reserved3 = 0, |
| | 266 | }); |
| | 267 | self.header_dirty = true; |
| | 268 | self.load_commands_dirty = true; |
| | 269 | self.debug_abbrev_section_dirty = true; |
| | 270 | } |
| | 271 | if (self.debug_aranges_section_index == null) { |
| | 272 | const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment; |
| | 273 | self.debug_aranges_section_index = @intCast(u16, dwarf_segment.sections.items.len); |
| | 274 | |
| | 275 | const file_size_hint = 160; |
| | 276 | const p_align = 16; |
| | 277 | const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null); |
| | 278 | |
| | 279 | log.debug("found dSym __debug_aranges free space 0x{x} to 0x{x}", .{ off, off + file_size_hint }); |
| | 280 | |
| | 281 | try dwarf_segment.addSection(allocator, .{ |
| | 282 | .sectname = makeStaticString("__debug_aranges"), |
| | 283 | .segname = makeStaticString("__DWARF"), |
| | 284 | .addr = dwarf_segment.inner.vmaddr + off, |
| | 285 | .size = file_size_hint, |
| | 286 | .offset = @intCast(u32, off), |
| | 287 | .@"align" = p_align, |
| | 288 | .reloff = 0, |
| | 289 | .nreloc = 0, |
| | 290 | .flags = macho.S_REGULAR, |
| | 291 | .reserved1 = 0, |
| | 292 | .reserved2 = 0, |
| | 293 | .reserved3 = 0, |
| | 294 | }); |
| | 295 | self.header_dirty = true; |
| | 296 | self.load_commands_dirty = true; |
| | 297 | self.debug_aranges_section_dirty = true; |
| | 298 | } |
| | 299 | if (self.debug_line_section_index == null) { |
| | 300 | const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment; |
| | 301 | self.debug_line_section_index = @intCast(u16, dwarf_segment.sections.items.len); |
| | 302 | |
| | 303 | const file_size_hint = 250; |
| | 304 | const p_align = 1; |
| | 305 | const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null); |
| | 306 | |
| | 307 | log.debug("found dSym __debug_line free space 0x{x} to 0x{x}", .{ off, off + file_size_hint }); |
| | 308 | |
| | 309 | try dwarf_segment.addSection(allocator, .{ |
| | 310 | .sectname = makeStaticString("__debug_line"), |
| | 311 | .segname = makeStaticString("__DWARF"), |
| | 312 | .addr = dwarf_segment.inner.vmaddr + off, |
| | 313 | .size = file_size_hint, |
| | 314 | .offset = @intCast(u32, off), |
| | 315 | .@"align" = p_align, |
| | 316 | .reloff = 0, |
| | 317 | .nreloc = 0, |
| | 318 | .flags = macho.S_REGULAR, |
| | 319 | .reserved1 = 0, |
| | 320 | .reserved2 = 0, |
| | 321 | .reserved3 = 0, |
| | 322 | }); |
| | 323 | self.header_dirty = true; |
| | 324 | self.load_commands_dirty = true; |
| | 325 | self.debug_line_header_dirty = true; |
| | 326 | } |
| 142 | } | 327 | } |
| 143 | | 328 | |
| 144 | pub fn flush(self: *DebugSymbols, allocator: *Allocator) !void { | 329 | pub fn flush(self: *DebugSymbols, allocator: *Allocator) !void { |