| ... | ... | @@ -129,6 +129,10 @@ pub fn getAtomRelocs(self: *ZigObject, atom: Atom) []const Relocation { |
| 129 | 129 | return relocs.items[0..atom.relocs.len]; |
| 130 | 130 | } |
| 131 | 131 | |
| 132 | pub fn freeAtomRelocs(self: *ZigObject, atom: Atom) void { |
| 133 | self.relocs.items[atom.relocs.pos].clearRetainingCapacity(); |
| 134 | } |
| 135 | |
| 132 | 136 | pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void { |
| 133 | 137 | _ = self; |
| 134 | 138 | _ = macho_file; |
| ... | ... | @@ -263,11 +267,42 @@ pub fn lowerAnonDecl( |
| 263 | 267 | @panic("TODO lowerAnonDecl"); |
| 264 | 268 | } |
| 265 | 269 | |
| 266 | | pub fn freeDecl(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.DeclIndex) void { |
| 270 | fn freeUnnamedConsts(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.DeclIndex) void { |
| 271 | const gpa = macho_file.base.comp.gpa; |
| 272 | const unnamed_consts = self.unnamed_consts.getPtr(decl_index) orelse return; |
| 273 | for (unnamed_consts.items) |sym_index| { |
| 274 | self.freeDeclMetadata(macho_file, sym_index); |
| 275 | } |
| 276 | unnamed_consts.clearAndFree(gpa); |
| 277 | } |
| 278 | |
| 279 | fn freeDeclMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void { |
| 267 | 280 | _ = self; |
| 268 | | _ = macho_file; |
| 269 | | _ = decl_index; |
| 270 | | @panic("TODO freeDecl"); |
| 281 | const gpa = macho_file.base.comp.gpa; |
| 282 | const sym = macho_file.getSymbol(sym_index); |
| 283 | sym.getAtom(macho_file).?.free(macho_file); |
| 284 | log.debug("adding %{d} to local symbols free list", .{sym_index}); |
| 285 | macho_file.symbols_free_list.append(gpa, sym_index) catch {}; |
| 286 | macho_file.symbols.items[sym_index] = .{}; |
| 287 | // TODO free GOT entry here |
| 288 | } |
| 289 | |
| 290 | pub fn freeDecl(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.DeclIndex) void { |
| 291 | const gpa = macho_file.base.comp.gpa; |
| 292 | const mod = macho_file.base.comp.module.?; |
| 293 | const decl = mod.declPtr(decl_index); |
| 294 | |
| 295 | log.debug("freeDecl {*}", .{decl}); |
| 296 | |
| 297 | if (self.decls.fetchRemove(decl_index)) |const_kv| { |
| 298 | var kv = const_kv; |
| 299 | const sym_index = kv.value.symbol_index; |
| 300 | self.freeDeclMetadata(macho_file, sym_index); |
| 301 | self.freeUnnamedConsts(macho_file, decl_index); |
| 302 | kv.value.exports.deinit(gpa); |
| 303 | } |
| 304 | |
| 305 | // TODO free decl in dSYM |
| 271 | 306 | } |
| 272 | 307 | |
| 273 | 308 | pub fn updateFunc( |
| ... | ... | @@ -278,13 +313,61 @@ pub fn updateFunc( |
| 278 | 313 | air: Air, |
| 279 | 314 | liveness: Liveness, |
| 280 | 315 | ) !void { |
| 281 | | _ = self; |
| 282 | | _ = macho_file; |
| 283 | | _ = mod; |
| 284 | | _ = func_index; |
| 285 | | _ = air; |
| 286 | | _ = liveness; |
| 287 | | @panic("TODO updateFunc"); |
| 316 | const tracy = trace(@src()); |
| 317 | defer tracy.end(); |
| 318 | |
| 319 | const gpa = macho_file.base.comp.gpa; |
| 320 | const func = mod.funcInfo(func_index); |
| 321 | const decl_index = func.owner_decl; |
| 322 | const decl = mod.declPtr(decl_index); |
| 323 | |
| 324 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); |
| 325 | self.freeUnnamedConsts(macho_file, decl_index); |
| 326 | macho_file.getSymbol(sym_index).getAtom(macho_file).?.freeRelocs(macho_file); |
| 327 | |
| 328 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 329 | defer code_buffer.deinit(); |
| 330 | |
| 331 | var decl_state: ?Dwarf.DeclState = null; // TODO: Dwarf |
| 332 | defer if (decl_state) |*ds| ds.deinit(); |
| 333 | |
| 334 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; |
| 335 | const res = try codegen.generateFunction( |
| 336 | &macho_file.base, |
| 337 | decl.srcLoc(mod), |
| 338 | func_index, |
| 339 | air, |
| 340 | liveness, |
| 341 | &code_buffer, |
| 342 | dio, |
| 343 | ); |
| 344 | |
| 345 | const code = switch (res) { |
| 346 | .ok => code_buffer.items, |
| 347 | .fail => |em| { |
| 348 | decl.analysis = .codegen_failure; |
| 349 | try mod.failed_decls.put(mod.gpa, decl_index, em); |
| 350 | return; |
| 351 | }, |
| 352 | }; |
| 353 | |
| 354 | const sect_index = try self.getDeclOutputSection(macho_file, decl, code); |
| 355 | try self.updateDeclCode(macho_file, decl_index, sym_index, sect_index, code); |
| 356 | |
| 357 | // if (decl_state) |*ds| { |
| 358 | // const sym = elf_file.symbol(sym_index); |
| 359 | // try self.dwarf.?.commitDeclState( |
| 360 | // mod, |
| 361 | // decl_index, |
| 362 | // sym.value, |
| 363 | // sym.atom(elf_file).?.size, |
| 364 | // ds, |
| 365 | // ); |
| 366 | // } |
| 367 | |
| 368 | // Since we updated the vaddr and the size, each corresponding export |
| 369 | // symbol also needs to be updated. |
| 370 | return self.updateExports(macho_file, mod, .{ .decl_index = decl_index }, mod.getDeclExports(decl_index)); |
| 288 | 371 | } |
| 289 | 372 | |
| 290 | 373 | pub fn updateDecl( |
| ... | ... | @@ -313,7 +396,7 @@ pub fn updateDecl( |
| 313 | 396 | } |
| 314 | 397 | |
| 315 | 398 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); |
| 316 | | // TODO: free relocs if any |
| 399 | macho_file.getSymbol(sym_index).getAtom(macho_file).?.freeRelocs(macho_file); |
| 317 | 400 | |
| 318 | 401 | const gpa = macho_file.base.comp.gpa; |
| 319 | 402 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | ... | @@ -431,7 +514,7 @@ fn updateDeclCode( |
| 431 | 514 | } |
| 432 | 515 | } else { |
| 433 | 516 | try atom.allocate(macho_file); |
| 434 | | // TODO: freeDeclMetadata in case of error |
| 517 | errdefer self.freeDeclMetadata(macho_file, sym_index); |
| 435 | 518 | |
| 436 | 519 | sym.value = 0; |
| 437 | 520 | sym.flags.needs_zig_got = true; |