| ... | @@ -8,9 +8,11 @@ data: std.ArrayListUnmanaged(u8) = .{}, | ... | @@ -8,9 +8,11 @@ data: std.ArrayListUnmanaged(u8) = .{}, |
| 8 | path: []const u8, | 8 | path: []const u8, |
| 9 | index: File.Index, | 9 | index: File.Index, |
| 10 | | 10 | |
| 11 | local_esyms: std.MultiArrayList(ElfSym) = .{}, | 11 | symtab: std.MultiArrayList(ElfSym) = .{}, |
| 12 | global_esyms: std.MultiArrayList(ElfSym) = .{}, | | |
| 13 | strtab: StringTable = .{}, | 12 | strtab: StringTable = .{}, |
| | 13 | symbols: std.ArrayListUnmanaged(Symbol) = .{}, |
| | 14 | symbols_extra: std.ArrayListUnmanaged(u32) = .{}, |
| | 15 | symbols_resolver: std.ArrayListUnmanaged(Elf.SymbolResolver.Index) = .{}, |
| 14 | local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, | 16 | local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 15 | global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, | 17 | global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 16 | globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, | 18 | globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, |
| ... | @@ -113,9 +115,11 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -113,9 +115,11 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { |
| 113 | | 115 | |
| 114 | pub fn deinit(self: *ZigObject, allocator: Allocator) void { | 116 | pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 115 | self.data.deinit(allocator); | 117 | self.data.deinit(allocator); |
| 116 | self.local_esyms.deinit(allocator); | 118 | self.symtab.deinit(allocator); |
| 117 | self.global_esyms.deinit(allocator); | | |
| 118 | self.strtab.deinit(allocator); | 119 | self.strtab.deinit(allocator); |
| | 120 | self.symbols.deinit(allocator); |
| | 121 | self.symbols_extra.deinit(allocator); |
| | 122 | self.symbols_resolver.deinit(allocator); |
| 119 | self.local_symbols.deinit(allocator); | 123 | self.local_symbols.deinit(allocator); |
| 120 | self.global_symbols.deinit(allocator); | 124 | self.global_symbols.deinit(allocator); |
| 121 | self.globals_lookup.deinit(allocator); | 125 | self.globals_lookup.deinit(allocator); |
| ... | @@ -263,51 +267,73 @@ fn saveDebugSectionsSizes(self: *ZigObject, elf_file: *Elf) void { | ... | @@ -263,51 +267,73 @@ fn saveDebugSectionsSizes(self: *ZigObject, elf_file: *Elf) void { |
| 263 | } | 267 | } |
| 264 | } | 268 | } |
| 265 | | 269 | |
| 266 | pub fn addLocalEsym(self: *ZigObject, allocator: Allocator) !Symbol.Index { | 270 | fn newSymbol(self: *ZigObject, allocator: Allocator, name_off: u32, st_bind: u4) !Symbol.Index { |
| 267 | try self.local_esyms.ensureUnusedCapacity(allocator, 1); | 271 | try self.symtab.ensureUnusedCapacity(allocator, 1); |
| 268 | const index = @as(Symbol.Index, @intCast(self.local_esyms.addOneAssumeCapacity())); | 272 | try self.symbols.ensureUnusedCapacity(allocator, 1); |
| 269 | var esym = ElfSym{ .elf_sym = Elf.null_sym }; | 273 | try self.symbols_extra.ensureUnusedCapacity(allocator, @sizeOf(Symbol.Extra)); |
| 270 | esym.elf_sym.st_info = elf.STB_LOCAL << 4; | 274 | |
| 271 | self.local_esyms.set(index, esym); | 275 | const index = self.addSymbolAssumeCapacity(); |
| | 276 | const sym = &self.symbols.items[index]; |
| | 277 | sym.name_offset = name_off; |
| | 278 | sym.extra = self.addSymbolExtraAssumeCapacity(.{}); |
| | 279 | |
| | 280 | const esym_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity()); |
| | 281 | const esym = ElfSym{ .elf_sym = .{ |
| | 282 | .st_value = 0, |
| | 283 | .st_name = name_off, |
| | 284 | .st_info = @as(u8, @intCast(st_bind)) << 4, |
| | 285 | .st_other = 0, |
| | 286 | .st_size = 0, |
| | 287 | .st_shndx = 0, |
| | 288 | } }; |
| | 289 | self.symtab.set(index, esym); |
| | 290 | sym.esym_index = esym_idx; |
| | 291 | |
| 272 | return index; | 292 | return index; |
| 273 | } | 293 | } |
| 274 | | 294 | |
| 275 | pub fn addGlobalEsym(self: *ZigObject, allocator: Allocator) !Symbol.Index { | 295 | fn newLocalSymbol(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index { |
| 276 | try self.global_esyms.ensureUnusedCapacity(allocator, 1); | 296 | try self.local_symbols.ensureUnusedCapacity(allocator, 1); |
| 277 | const index = @as(Symbol.Index, @intCast(self.global_esyms.addOneAssumeCapacity())); | 297 | const fake_index: Symbol.Index = @intCast(self.local_symbols.items.len); |
| 278 | var esym = ElfSym{ .elf_sym = Elf.null_sym }; | 298 | const index = try self.newSymbol(allocator, name_off, elf.STB_LOCAL); |
| 279 | esym.elf_sym.st_info = elf.STB_GLOBAL << 4; | 299 | self.local_symbols.appendAssumeCapacity(index); |
| 280 | self.global_esyms.set(index, esym); | 300 | return fake_index; |
| 281 | return index | global_symbol_bit; | | |
| 282 | } | 301 | } |
| 283 | | 302 | |
| 284 | pub fn newAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index { | 303 | fn newGlobalSymbol(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index { |
| 285 | const gpa = elf_file.base.comp.gpa; | 304 | try self.global_symbols.ensureUnusedCapacity(allocator, 1); |
| 286 | const atom_index = try self.addAtom(gpa); | 305 | const fake_index: Symbol.Index = @intCast(self.global_symbols.items.len); |
| 287 | const symbol_index = try elf_file.addSymbol(); | 306 | const index = try self.newSymbol(allocator, name_off, elf.STB_GLOBAL); |
| 288 | const esym_index = try self.addLocalEsym(gpa); | 307 | self.global_symbols.appendAssumeCapacity(index); |
| 289 | | 308 | return fake_index | global_symbol_bit; |
| 290 | try self.atoms_indexes.append(gpa, atom_index); | 309 | } |
| 291 | try self.local_symbols.append(gpa, symbol_index); | | |
| 292 | | | |
| 293 | const symbol_ptr = elf_file.symbol(symbol_index); | | |
| 294 | symbol_ptr.file_index = self.index; | | |
| 295 | symbol_ptr.ref = .{ .index = atom_index, .file = self.index }; | | |
| 296 | symbol_ptr.extra_index = try elf_file.addSymbolExtra(.{}); | | |
| 297 | | 310 | |
| 298 | self.local_esyms.items(.shndx)[esym_index] = atom_index; | 311 | fn newAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Atom.Index { |
| 299 | self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM; | 312 | try self.atoms.ensureUnusedCapacity(allocator, 1); |
| 300 | symbol_ptr.esym_index = esym_index; | 313 | try self.atoms_extra.ensureUnusedCapacity(allocator, @sizeOf(Atom.Extra)); |
| | 314 | try self.atoms_indexes.ensureUnusedCapacity(allocator, 1); |
| | 315 | try self.relocs.ensureUnusedCapacity(allocator, 1); |
| 301 | | 316 | |
| 302 | // TODO I'm thinking that maybe we shouldn' set this value unless it's actually needed? | 317 | const index = self.addAtomAssumeCapacity(); |
| 303 | const relocs_index = @as(u32, @intCast(self.relocs.items.len)); | 318 | self.atoms_indexes.appendAssumeCapacity(index); |
| 304 | const relocs = try self.relocs.addOne(gpa); | 319 | const atom_ptr = self.atom(index).?; |
| 305 | relocs.* = .{}; | 320 | atom_ptr.name_offset = name_off; |
| 306 | | 321 | |
| 307 | const atom_ptr = self.atom(atom_index).?; | 322 | const relocs_index: u32 = @intCast(self.relocs.items.len); |
| | 323 | self.relocs.addOneAssumeCapacity().* = .{}; |
| 308 | atom_ptr.relocs_section_index = relocs_index; | 324 | atom_ptr.relocs_section_index = relocs_index; |
| 309 | | 325 | |
| 310 | return symbol_index; | 326 | return index; |
| | 327 | } |
| | 328 | |
| | 329 | fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index { |
| | 330 | const atom_index = try self.newAtom(allocator, name_off); |
| | 331 | const sym_index = try self.newLocalSymbol(allocator, name_off); |
| | 332 | const sym = self.symbol(sym_index); |
| | 333 | sym.ref = .{ .index = atom_index, .file = self.index }; |
| | 334 | self.symtab.items(.shndx)[sym.esym_index] = atom_index; |
| | 335 | self.symtab.items(.elf_sym)[sym.esym_index].st_shndx = SHN_ATOM; |
| | 336 | return sym_index; |
| 311 | } | 337 | } |
| 312 | | 338 | |
| 313 | /// TODO actually create fake input shdrs and return that instead. | 339 | /// TODO actually create fake input shdrs and return that instead. |
| ... | @@ -322,48 +348,47 @@ pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.E | ... | @@ -322,48 +348,47 @@ pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.E |
| 322 | return shdr; | 348 | return shdr; |
| 323 | } | 349 | } |
| 324 | | 350 | |
| 325 | pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) void { | 351 | pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) !void { |
| 326 | for (self.globals(), 0..) |index, i| { | 352 | const gpa = elf_file.base.comp.gpa; |
| 327 | const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit; | | |
| 328 | const esym = self.global_esyms.items(.elf_sym)[i]; | | |
| 329 | const shndx = self.global_esyms.items(.shndx)[i]; | | |
| 330 | | | |
| 331 | if (esym.st_shndx == elf.SHN_UNDEF) continue; | | |
| 332 | | 353 | |
| | 354 | for (self.global_symbols.items, 0..) |index, i| { |
| | 355 | const global = &self.symbols.items[index]; |
| | 356 | const esym = global.elfSym(elf_file); |
| | 357 | const shndx = self.symtab.items(.shndx)[global.esym_index]; |
| 333 | if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) { | 358 | if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) { |
| 334 | assert(esym.st_shndx == SHN_ATOM); | 359 | assert(esym.st_shndx == SHN_ATOM); |
| 335 | const atom_ptr = self.atom(shndx) orelse continue; | 360 | const atom_ptr = self.atom(shndx) orelse continue; |
| 336 | if (!atom_ptr.alive) continue; | 361 | if (!atom_ptr.alive) continue; |
| 337 | } | 362 | } |
| 338 | | 363 | |
| 339 | const global = elf_file.symbol(index); | 364 | const resolv = &self.symbols_resolver.items[i]; |
| 340 | if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) { | 365 | const gop = try elf_file.resolver.getOrPut(gpa, .{ |
| 341 | const atom_index = switch (esym.st_shndx) { | 366 | .index = @intCast(i | global_symbol_bit), |
| 342 | elf.SHN_ABS, elf.SHN_COMMON => 0, | 367 | .file = self.index, |
| 343 | SHN_ATOM => shndx, | 368 | }, elf_file); |
| 344 | else => unreachable, | 369 | if (!gop.found_existing) { |
| 345 | }; | 370 | gop.ref.* = .{ .index = 0, .file = 0 }; |
| 346 | global.value = @intCast(esym.st_value); | 371 | } |
| 347 | global.ref = .{ .index = atom_index, .file = self.index }; | 372 | resolv.* = gop.index; |
| 348 | global.esym_index = esym_index; | 373 | |
| 349 | global.file_index = self.index; | 374 | if (esym.st_shndx == elf.SHN_UNDEF) continue; |
| 350 | global.version_index = elf_file.default_sym_version; | 375 | if (elf_file.symbol(gop.ref.*) == null) { |
| 351 | if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true; | 376 | gop.ref.* = .{ .index = @intCast(i | global_symbol_bit), .file = self.index }; |
| | 377 | continue; |
| | 378 | } |
| | 379 | |
| | 380 | if (self.asFile().symbolRank(esym, !self.alive) < elf_file.symbol(gop.ref.*).?.symbolRank(elf_file)) { |
| | 381 | gop.ref.* = .{ .index = @intCast(i | global_symbol_bit), .file = self.index }; |
| 352 | } | 382 | } |
| 353 | } | 383 | } |
| 354 | } | 384 | } |
| 355 | | 385 | |
| 356 | pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void { | 386 | pub fn claimUnresolved(self: *ZigObject, elf_file: *Elf) void { |
| 357 | for (self.globals(), 0..) |index, i| { | 387 | for (self.global_symbols.items, 0..) |index, i| { |
| 358 | const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit; | 388 | const global = &self.symbols.items[index]; |
| 359 | const esym = self.global_esyms.items(.elf_sym)[i]; | 389 | const esym = self.symtab.items(.elf_sym)[index]; |
| 360 | | | |
| 361 | if (esym.st_shndx != elf.SHN_UNDEF) continue; | 390 | if (esym.st_shndx != elf.SHN_UNDEF) continue; |
| 362 | | 391 | if (elf_file.symbol(self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file)) != null) continue; |
| 363 | const global = elf_file.symbol(index); | | |
| 364 | if (global.file(elf_file)) |_| { | | |
| 365 | if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF) continue; | | |
| 366 | } | | |
| 367 | | 392 | |
| 368 | const is_import = blk: { | 393 | const is_import = blk: { |
| 369 | if (!elf_file.isEffectivelyDynLib()) break :blk false; | 394 | if (!elf_file.isEffectivelyDynLib()) break :blk false; |
| ... | @@ -374,29 +399,36 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void { | ... | @@ -374,29 +399,36 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void { |
| 374 | | 399 | |
| 375 | global.value = 0; | 400 | global.value = 0; |
| 376 | global.ref = .{ .index = 0, .file = 0 }; | 401 | global.ref = .{ .index = 0, .file = 0 }; |
| 377 | global.esym_index = esym_index; | 402 | global.esym_index = @intCast(index); |
| 378 | global.file_index = self.index; | 403 | global.file_index = self.index; |
| 379 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; | 404 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; |
| 380 | global.flags.import = is_import; | 405 | global.flags.import = is_import; |
| | 406 | |
| | 407 | const idx = self.symbols_resolver.items[i]; |
| | 408 | elf_file.resolver.values.items[idx - 1] = .{ .index = @intCast(i | global_symbol_bit), .file = self.index }; |
| 381 | } | 409 | } |
| 382 | } | 410 | } |
| 383 | | 411 | |
| 384 | pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void { | 412 | pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void { |
| 385 | for (self.globals(), 0..) |index, i| { | 413 | for (self.global_symbols.items, 0..) |index, i| { |
| 386 | const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit; | 414 | const global = &self.symbols.items[index]; |
| 387 | const esym = self.global_esyms.items(.elf_sym)[i]; | 415 | const esym = self.symtab.items(.elf_sym)[index]; |
| 388 | | | |
| 389 | if (esym.st_shndx != elf.SHN_UNDEF) continue; | 416 | if (esym.st_shndx != elf.SHN_UNDEF) continue; |
| | 417 | if (elf_file.symbol(self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file)) != null) continue; |
| 390 | | 418 | |
| 391 | const global = elf_file.symbol(index); | 419 | // TODO: audit this |
| 392 | if (global.file(elf_file)) |file| { | 420 | // const global = elf_file.symbol(index); |
| 393 | if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue; | 421 | // if (global.file(elf_file)) |file| { |
| 394 | } | 422 | // if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue; |
| | 423 | // } |
| 395 | | 424 | |
| 396 | global.value = 0; | 425 | global.value = 0; |
| 397 | global.ref = .{ .index = 0, .file = 0 }; | 426 | global.ref = .{ .index = 0, .file = 0 }; |
| 398 | global.esym_index = esym_index; | 427 | global.esym_index = @intCast(index); |
| 399 | global.file_index = self.index; | 428 | global.file_index = self.index; |
| | 429 | |
| | 430 | const idx = self.symbols_resolver.items[i]; |
| | 431 | elf_file.resolver.items[idx - 1] = .{ .index = @intCast(i | global_symbol_bit), .file = self.index }; |
| 400 | } | 432 | } |
| 401 | } | 433 | } |
| 402 | | 434 | |
| ... | @@ -419,12 +451,14 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { | ... | @@ -419,12 +451,14 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { |
| 419 | } | 451 | } |
| 420 | | 452 | |
| 421 | pub fn markLive(self: *ZigObject, elf_file: *Elf) void { | 453 | pub fn markLive(self: *ZigObject, elf_file: *Elf) void { |
| 422 | for (self.globals(), 0..) |index, i| { | 454 | for (self.global_symbols.items, 0..) |index, i| { |
| 423 | const esym = self.global_esyms.items(.elf_sym)[i]; | 455 | const global = self.symbols.items[index]; |
| | 456 | const esym = self.symtab.items(.elf_sym)[index]; |
| 424 | if (esym.st_bind() == elf.STB_WEAK) continue; | 457 | if (esym.st_bind() == elf.STB_WEAK) continue; |
| 425 | | 458 | |
| 426 | const global = elf_file.symbol(index); | 459 | const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file); |
| 427 | const file = global.file(elf_file) orelse continue; | 460 | const sym = elf_file.symbol(ref) orelse continue; |
| | 461 | const file = sym.file(elf_file).?; |
| 428 | const should_keep = esym.st_shndx == elf.SHN_UNDEF or | 462 | const should_keep = esym.st_shndx == elf.SHN_UNDEF or |
| 429 | (esym.st_shndx == elf.SHN_COMMON and global.elfSym(elf_file).st_shndx != elf.SHN_COMMON); | 463 | (esym.st_shndx == elf.SHN_COMMON and global.elfSym(elf_file).st_shndx != elf.SHN_COMMON); |
| 430 | if (should_keep and !file.isAlive()) { | 464 | if (should_keep and !file.isAlive()) { |
| ... | @@ -434,14 +468,36 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void { | ... | @@ -434,14 +468,36 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void { |
| 434 | } | 468 | } |
| 435 | } | 469 | } |
| 436 | | 470 | |
| 437 | pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{OutOfMemory}!void { | 471 | pub fn markImportsExports(self: *Object, elf_file: *Elf) void { |
| 438 | for (self.globals(), 0..) |index, i| { | 472 | for (0..self.global_symbols.items.len) |i| { |
| 439 | const esym = self.global_esyms.items(.elf_sym)[i]; | 473 | const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file); |
| 440 | const shndx = self.global_esyms.items(.shndx)[i]; | 474 | const sym = elf_file.symbol(ref) orelse continue; |
| 441 | const global = elf_file.symbol(index); | 475 | const file = sym.file(elf_file).?; |
| 442 | const global_file = global.file(elf_file) orelse continue; | 476 | if (sym.version_index == elf.VER_NDX_LOCAL) continue; |
| | 477 | const vis = @as(elf.STV, @enumFromInt(sym.elfSym(elf_file).st_other)); |
| | 478 | if (vis == .HIDDEN) continue; |
| | 479 | if (file == .shared_object and !sym.isAbs(elf_file)) { |
| | 480 | sym.flags.import = true; |
| | 481 | continue; |
| | 482 | } |
| | 483 | if (file.index() == self.index) { |
| | 484 | sym.flags.@"export" = true; |
| | 485 | if (elf_file.isEffectivelyDynLib() and vis != .PROTECTED) { |
| | 486 | sym.flags.import = true; |
| | 487 | } |
| | 488 | } |
| | 489 | } |
| | 490 | } |
| 443 | | 491 | |
| 444 | if (self.index == global_file.index() or | 492 | pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{OutOfMemory}!void { |
| | 493 | for (self.global_symbols.items, 0..) |index, i| { |
| | 494 | const esym = self.symtab.items(.elf_sym)[index]; |
| | 495 | const shndx = self.symtab.items(.shndx)[index]; |
| | 496 | const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file); |
| | 497 | const ref_sym = elf_file.symbol(ref) orelse continue; |
| | 498 | const ref_file = ref_sym.file(elf_file).?; |
| | 499 | |
| | 500 | if (self.index == ref_file.index() or |
| 445 | esym.st_shndx == elf.SHN_UNDEF or | 501 | esym.st_shndx == elf.SHN_UNDEF or |
| 446 | esym.st_bind() == elf.STB_WEAK or | 502 | esym.st_bind() == elf.STB_WEAK or |
| 447 | esym.st_shndx == elf.SHN_COMMON) continue; | 503 | esym.st_shndx == elf.SHN_COMMON) continue; |
| ... | @@ -451,7 +507,7 @@ pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{O | ... | @@ -451,7 +507,7 @@ pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{O |
| 451 | if (!atom_ptr.alive) continue; | 507 | if (!atom_ptr.alive) continue; |
| 452 | } | 508 | } |
| 453 | | 509 | |
| 454 | const gop = try dupes.getOrPut(index); | 510 | const gop = try dupes.getOrPut(self.symbols_resolver.items[i]); |
| 455 | if (!gop.found_existing) { | 511 | if (!gop.found_existing) { |
| 456 | gop.value_ptr.* = .{}; | 512 | gop.value_ptr.* = .{}; |
| 457 | } | 513 | } |
| ... | @@ -483,12 +539,13 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -483,12 +539,13 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void { |
| 483 | pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) error{OutOfMemory}!void { | 539 | pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) error{OutOfMemory}!void { |
| 484 | const gpa = elf_file.base.comp.gpa; | 540 | const gpa = elf_file.base.comp.gpa; |
| 485 | | 541 | |
| 486 | try ar_symtab.symtab.ensureUnusedCapacity(gpa, self.globals().len); | 542 | try ar_symtab.symtab.ensureUnusedCapacity(gpa, self.global_symbols.items.len); |
| 487 | | 543 | |
| 488 | for (self.globals()) |global_index| { | 544 | for (self.global_symbols.items, 0..) |index, i| { |
| 489 | const global = elf_file.symbol(global_index); | 545 | const global = self.symbols.items[index]; |
| 490 | const file_ptr = global.file(elf_file).?; | 546 | const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file); |
| 491 | assert(file_ptr.index() == self.index); | 547 | const sym = elf_file.symbol(ref).?; |
| | 548 | assert(sym.file(elf_file).?.index() == self.index); |
| 492 | if (global.outputShndx(elf_file) == null) continue; | 549 | if (global.outputShndx(elf_file) == null) continue; |
| 493 | | 550 | |
| 494 | const off = try ar_symtab.strtab.insert(gpa, global.name(elf_file)); | 551 | const off = try ar_symtab.strtab.insert(gpa, global.name(elf_file)); |
| ... | @@ -530,33 +587,9 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -530,33 +587,9 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void { |
| 530 | } | 587 | } |
| 531 | } | 588 | } |
| 532 | | 589 | |
| 533 | inline fn isGlobal(index: Symbol.Index) bool { | | |
| 534 | return index & global_symbol_bit != 0; | | |
| 535 | } | | |
| 536 | | | |
| 537 | pub fn symbol(self: ZigObject, index: Symbol.Index) Symbol.Index { | | |
| 538 | const actual_index = index & symbol_mask; | | |
| 539 | if (isGlobal(index)) return self.globals()[actual_index]; | | |
| 540 | return self.locals()[actual_index]; | | |
| 541 | } | | |
| 542 | | | |
| 543 | pub fn elfSym(self: *ZigObject, index: Symbol.Index) *elf.Elf64_Sym { | | |
| 544 | const actual_index = index & symbol_mask; | | |
| 545 | if (isGlobal(index)) return &self.global_esyms.items(.elf_sym)[actual_index]; | | |
| 546 | return &self.local_esyms.items(.elf_sym)[actual_index]; | | |
| 547 | } | | |
| 548 | | | |
| 549 | pub fn locals(self: ZigObject) []const Symbol.Index { | | |
| 550 | return self.local_symbols.items; | | |
| 551 | } | | |
| 552 | | | |
| 553 | pub fn globals(self: ZigObject) []const Symbol.Index { | | |
| 554 | return self.global_symbols.items; | | |
| 555 | } | | |
| 556 | | | |
| 557 | pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void { | 590 | pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void { |
| 558 | for (self.locals()) |local_index| { | 591 | for (self.local_symbols.items) |index| { |
| 559 | const local = elf_file.symbol(local_index); | 592 | const local = &self.symbols.items[index]; |
| 560 | if (local.atom(elf_file)) |atom_ptr| if (!atom_ptr.alive) continue; | 593 | if (local.atom(elf_file)) |atom_ptr| if (!atom_ptr.alive) continue; |
| 561 | const esym = local.elfSym(elf_file); | 594 | const esym = local.elfSym(elf_file); |
| 562 | switch (esym.st_type()) { | 595 | switch (esym.st_type()) { |
| ... | @@ -564,22 +597,23 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -564,22 +597,23 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void { |
| 564 | else => {}, | 597 | else => {}, |
| 565 | } | 598 | } |
| 566 | local.flags.output_symtab = true; | 599 | local.flags.output_symtab = true; |
| 567 | try local.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file); | 600 | local.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file); |
| 568 | self.output_symtab_ctx.nlocals += 1; | 601 | self.output_symtab_ctx.nlocals += 1; |
| 569 | self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1; | 602 | self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1; |
| 570 | } | 603 | } |
| 571 | | 604 | |
| 572 | for (self.globals()) |global_index| { | 605 | for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| { |
| 573 | const global = elf_file.symbol(global_index); | 606 | const global = &self.symbols.items[index]; |
| 574 | const file_ptr = global.file(elf_file) orelse continue; | 607 | const ref = elf_file.resolver.items[resolv]; |
| 575 | if (file_ptr.index() != self.index) continue; | 608 | const ref_sym = elf_file.symbol(ref) orelse continue; |
| | 609 | if (ref_sym.file(elf_file).?.index() != self.index) continue; |
| 576 | if (global.atom(elf_file)) |atom_ptr| if (!atom_ptr.alive) continue; | 610 | if (global.atom(elf_file)) |atom_ptr| if (!atom_ptr.alive) continue; |
| 577 | global.flags.output_symtab = true; | 611 | global.flags.output_symtab = true; |
| 578 | if (global.isLocal(elf_file)) { | 612 | if (global.isLocal(elf_file)) { |
| 579 | try global.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file); | 613 | global.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file); |
| 580 | self.output_symtab_ctx.nlocals += 1; | 614 | self.output_symtab_ctx.nlocals += 1; |
| 581 | } else { | 615 | } else { |
| 582 | try global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file); | 616 | global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file); |
| 583 | self.output_symtab_ctx.nglobals += 1; | 617 | self.output_symtab_ctx.nglobals += 1; |
| 584 | } | 618 | } |
| 585 | self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1; | 619 | self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1; |
| ... | @@ -587,8 +621,8 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -587,8 +621,8 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void { |
| 587 | } | 621 | } |
| 588 | | 622 | |
| 589 | pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { | 623 | pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { |
| 590 | for (self.locals()) |local_index| { | 624 | for (self.local_symbols.items) |index| { |
| 591 | const local = elf_file.symbol(local_index); | 625 | const local = &self.symbols.items[index]; |
| 592 | const idx = local.outputSymtabIndex(elf_file) orelse continue; | 626 | const idx = local.outputSymtabIndex(elf_file) orelse continue; |
| 593 | const out_sym = &elf_file.symtab.items[idx]; | 627 | const out_sym = &elf_file.symtab.items[idx]; |
| 594 | out_sym.st_name = @intCast(elf_file.strtab.items.len); | 628 | out_sym.st_name = @intCast(elf_file.strtab.items.len); |
| ... | @@ -597,10 +631,11 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { | ... | @@ -597,10 +631,11 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { |
| 597 | local.setOutputSym(elf_file, out_sym); | 631 | local.setOutputSym(elf_file, out_sym); |
| 598 | } | 632 | } |
| 599 | | 633 | |
| 600 | for (self.globals()) |global_index| { | 634 | for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| { |
| 601 | const global = elf_file.symbol(global_index); | 635 | const global = self.symbols.items[index]; |
| 602 | const file_ptr = global.file(elf_file) orelse continue; | 636 | const ref = elf_file.resolver.items[resolv]; |
| 603 | if (file_ptr.index() != self.index) continue; | 637 | const ref_sym = elf_file.symbol(ref) orelse continue; |
| | 638 | if (ref_sym.file(elf_file).?.index() != self.index) continue; |
| 604 | const idx = global.outputSymtabIndex(elf_file) orelse continue; | 639 | const idx = global.outputSymtabIndex(elf_file) orelse continue; |
| 605 | const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); | 640 | const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); |
| 606 | elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file)); | 641 | elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file)); |
| ... | @@ -611,10 +646,6 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { | ... | @@ -611,10 +646,6 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { |
| 611 | } | 646 | } |
| 612 | } | 647 | } |
| 613 | | 648 | |
| 614 | pub fn asFile(self: *ZigObject) File { | | |
| 615 | return .{ .zig_object = self }; | | |
| 616 | } | | |
| 617 | | | |
| 618 | /// Returns atom's code. | 649 | /// Returns atom's code. |
| 619 | /// Caller owns the memory. | 650 | /// Caller owns the memory. |
| 620 | pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 { | 651 | pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 { |
| ... | @@ -755,8 +786,8 @@ pub fn getOrCreateMetadataForLazySymbol( | ... | @@ -755,8 +786,8 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 755 | }; | 786 | }; |
| 756 | switch (metadata.state.*) { | 787 | switch (metadata.state.*) { |
| 757 | .unused => { | 788 | .unused => { |
| 758 | const symbol_index = try self.newAtom(elf_file); | 789 | const symbol_index = try self.newSymbolWithAtom(gpa, 0); |
| 759 | const sym = elf_file.symbol(symbol_index); | 790 | const sym = self.symbol(symbol_index); |
| 760 | sym.flags.needs_zig_got = true; | 791 | sym.flags.needs_zig_got = true; |
| 761 | metadata.symbol_index.* = symbol_index; | 792 | metadata.symbol_index.* = symbol_index; |
| 762 | }, | 793 | }, |
| ... | @@ -817,10 +848,10 @@ pub fn getOrCreateMetadataForDecl( | ... | @@ -817,10 +848,10 @@ pub fn getOrCreateMetadataForDecl( |
| 817 | const gop = try self.decls.getOrPut(gpa, decl_index); | 848 | const gop = try self.decls.getOrPut(gpa, decl_index); |
| 818 | if (!gop.found_existing) { | 849 | if (!gop.found_existing) { |
| 819 | const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded; | 850 | const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded; |
| 820 | const symbol_index = try self.newAtom(elf_file); | 851 | const symbol_index = try self.newSymbolWithAtom(gpa, 0); |
| 821 | const mod = elf_file.base.comp.module.?; | 852 | const mod = elf_file.base.comp.module.?; |
| 822 | const decl = mod.declPtr(decl_index); | 853 | const decl = mod.declPtr(decl_index); |
| 823 | const sym = elf_file.symbol(symbol_index); | 854 | const sym = self.symbol(symbol_index); |
| 824 | if (decl.getOwnedVariable(mod)) |variable| { | 855 | if (decl.getOwnedVariable(mod)) |variable| { |
| 825 | if (variable.is_threadlocal and any_non_single_threaded) { | 856 | if (variable.is_threadlocal and any_non_single_threaded) { |
| 826 | sym.flags.is_tls = true; | 857 | sym.flags.is_tls = true; |
| ... | @@ -1064,7 +1095,7 @@ pub fn updateFunc( | ... | @@ -1064,7 +1095,7 @@ pub fn updateFunc( |
| 1064 | | 1095 | |
| 1065 | const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); | 1096 | const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); |
| 1066 | self.freeUnnamedConsts(elf_file, decl_index); | 1097 | self.freeUnnamedConsts(elf_file, decl_index); |
| 1067 | elf_file.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); | 1098 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); |
| 1068 | | 1099 | |
| 1069 | var code_buffer = std.ArrayList(u8).init(gpa); | 1100 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1070 | defer code_buffer.deinit(); | 1101 | defer code_buffer.deinit(); |
| ... | @@ -1096,7 +1127,7 @@ pub fn updateFunc( | ... | @@ -1096,7 +1127,7 @@ pub fn updateFunc( |
| 1096 | try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_FUNC); | 1127 | try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_FUNC); |
| 1097 | | 1128 | |
| 1098 | if (decl_state) |*ds| { | 1129 | if (decl_state) |*ds| { |
| 1099 | const sym = elf_file.symbol(sym_index); | 1130 | const sym = self.symbol(sym_index); |
| 1100 | try self.dwarf.?.commitDeclState( | 1131 | try self.dwarf.?.commitDeclState( |
| 1101 | pt, | 1132 | pt, |
| 1102 | decl_index, | 1133 | decl_index, |
| ... | @@ -1130,13 +1161,13 @@ pub fn updateDecl( | ... | @@ -1130,13 +1161,13 @@ pub fn updateDecl( |
| 1130 | const variable = decl.getOwnedVariable(mod).?; | 1161 | const variable = decl.getOwnedVariable(mod).?; |
| 1131 | const name = decl.name.toSlice(&mod.intern_pool); | 1162 | const name = decl.name.toSlice(&mod.intern_pool); |
| 1132 | const lib_name = variable.lib_name.toSlice(&mod.intern_pool); | 1163 | const lib_name = variable.lib_name.toSlice(&mod.intern_pool); |
| 1133 | const esym_index = try self.getGlobalSymbol(elf_file, name, lib_name); | 1164 | const sym_index = try self.getGlobalSymbol(elf_file, name, lib_name); |
| 1134 | elf_file.symbol(self.symbol(esym_index)).flags.needs_got = true; | 1165 | self.symbol(sym_index).flags.needs_got = true; |
| 1135 | return; | 1166 | return; |
| 1136 | } | 1167 | } |
| 1137 | | 1168 | |
| 1138 | const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); | 1169 | const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); |
| 1139 | elf_file.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); | 1170 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); |
| 1140 | | 1171 | |
| 1141 | const gpa = elf_file.base.comp.gpa; | 1172 | const gpa = elf_file.base.comp.gpa; |
| 1142 | var code_buffer = std.ArrayList(u8).init(gpa); | 1173 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | @@ -1174,7 +1205,7 @@ pub fn updateDecl( | ... | @@ -1174,7 +1205,7 @@ pub fn updateDecl( |
| 1174 | try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_OBJECT); | 1205 | try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_OBJECT); |
| 1175 | | 1206 | |
| 1176 | if (decl_state) |*ds| { | 1207 | if (decl_state) |*ds| { |
| 1177 | const sym = elf_file.symbol(sym_index); | 1208 | const sym = self.symbol(sym_index); |
| 1178 | try self.dwarf.?.commitDeclState( | 1209 | try self.dwarf.?.commitDeclState( |
| 1179 | pt, | 1210 | pt, |
| 1180 | decl_index, | 1211 | decl_index, |
| ... | @@ -1323,7 +1354,8 @@ fn lowerConst( | ... | @@ -1323,7 +1354,8 @@ fn lowerConst( |
| 1323 | var code_buffer = std.ArrayList(u8).init(gpa); | 1354 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1324 | defer code_buffer.deinit(); | 1355 | defer code_buffer.deinit(); |
| 1325 | | 1356 | |
| 1326 | const sym_index = try self.newAtom(elf_file); | 1357 | const name_off = try self.addString(gpa, name); |
| | 1358 | const sym_index = try self.newSymbolWithAtom(gpa, name_off); |
| 1327 | | 1359 | |
| 1328 | const res = try codegen.generateSymbol( | 1360 | const res = try codegen.generateSymbol( |
| 1329 | &elf_file.base, | 1361 | &elf_file.base, |
| ... | @@ -1339,27 +1371,19 @@ fn lowerConst( | ... | @@ -1339,27 +1371,19 @@ fn lowerConst( |
| 1339 | .fail => |em| return .{ .fail = em }, | 1371 | .fail => |em| return .{ .fail = em }, |
| 1340 | }; | 1372 | }; |
| 1341 | | 1373 | |
| 1342 | const local_sym = elf_file.symbol(sym_index); | 1374 | const local_sym = self.symbol(sym_index); |
| 1343 | const name_str_index = try self.strtab.insert(gpa, name); | 1375 | const local_esym = local_sym.elfSym(elf_file); |
| 1344 | local_sym.name_offset = name_str_index; | | |
| 1345 | const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index]; | | |
| 1346 | local_esym.st_name = name_str_index; | | |
| 1347 | local_esym.st_info |= elf.STT_OBJECT; | 1376 | local_esym.st_info |= elf.STT_OBJECT; |
| 1348 | local_esym.st_size = code.len; | 1377 | local_esym.st_size = code.len; |
| 1349 | const atom_ptr = local_sym.atom(elf_file).?; | 1378 | const atom_ptr = local_sym.atom(elf_file).?; |
| 1350 | atom_ptr.alive = true; | 1379 | atom_ptr.alive = true; |
| 1351 | atom_ptr.name_offset = name_str_index; | | |
| 1352 | atom_ptr.alignment = required_alignment; | 1380 | atom_ptr.alignment = required_alignment; |
| 1353 | atom_ptr.size = code.len; | 1381 | atom_ptr.size = code.len; |
| 1354 | atom_ptr.output_section_index = output_section_index; | 1382 | atom_ptr.output_section_index = output_section_index; |
| 1355 | | 1383 | |
| 1356 | try atom_ptr.allocate(elf_file); | 1384 | try atom_ptr.allocate(elf_file); |
| 1357 | // TODO rename and re-audit this method | | |
| 1358 | errdefer self.freeDeclMetadata(elf_file, sym_index); | 1385 | errdefer self.freeDeclMetadata(elf_file, sym_index); |
| 1359 | | 1386 | |
| 1360 | local_sym.value = 0; | | |
| 1361 | local_esym.st_value = 0; | | |
| 1362 | | | |
| 1363 | const shdr = elf_file.shdrs.items[output_section_index]; | 1387 | const shdr = elf_file.shdrs.items[output_section_index]; |
| 1364 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); | 1388 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1365 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 1389 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| ... | @@ -1401,9 +1425,9 @@ pub fn updateExports( | ... | @@ -1401,9 +1425,9 @@ pub fn updateExports( |
| 1401 | }, | 1425 | }, |
| 1402 | }; | 1426 | }; |
| 1403 | const sym_index = metadata.symbol_index; | 1427 | const sym_index = metadata.symbol_index; |
| 1404 | const esym_index = elf_file.symbol(sym_index).esym_index; | 1428 | const esym_index = self.symbol(sym_index).esym_index; |
| 1405 | const esym = self.local_esyms.items(.elf_sym)[esym_index]; | 1429 | const esym = self.symtab.items(.elf_sym)[esym_index]; |
| 1406 | const esym_shndx = self.local_esyms.items(.shndx)[esym_index]; | 1430 | const esym_shndx = self.symtab.items(.shndx)[esym_index]; |
| 1407 | | 1431 | |
| 1408 | for (export_indices) |export_idx| { | 1432 | for (export_indices) |export_idx| { |
| 1409 | const exp = mod.all_exports.items[export_idx]; | 1433 | const exp = mod.all_exports.items[export_idx]; |
| ... | @@ -1437,22 +1461,27 @@ pub fn updateExports( | ... | @@ -1437,22 +1461,27 @@ pub fn updateExports( |
| 1437 | const stt_bits: u8 = @as(u4, @truncate(esym.st_info)); | 1461 | const stt_bits: u8 = @as(u4, @truncate(esym.st_info)); |
| 1438 | const exp_name = exp.opts.name.toSlice(&mod.intern_pool); | 1462 | const exp_name = exp.opts.name.toSlice(&mod.intern_pool); |
| 1439 | const name_off = try self.strtab.insert(gpa, exp_name); | 1463 | const name_off = try self.strtab.insert(gpa, exp_name); |
| 1440 | const global_esym_index = if (metadata.@"export"(self, exp_name)) |exp_index| | 1464 | const global_sym_index = if (metadata.@"export"(self, exp_name)) |exp_index| |
| 1441 | exp_index.* | 1465 | exp_index.* |
| 1442 | else blk: { | 1466 | else blk: { |
| 1443 | const global_esym_index = try self.getGlobalSymbol(elf_file, exp_name, null); | 1467 | const global_sym_index = try self.getGlobalSymbol(elf_file, exp_name, null); |
| 1444 | try metadata.exports.append(gpa, global_esym_index); | 1468 | try metadata.exports.append(gpa, global_sym_index); |
| 1445 | break :blk global_esym_index; | 1469 | break :blk global_sym_index; |
| 1446 | }; | 1470 | }; |
| 1447 | | 1471 | |
| 1448 | const actual_esym_index = global_esym_index & symbol_mask; | 1472 | const value = self.symbol(sym_index).value; |
| 1449 | const global_esym = &self.global_esyms.items(.elf_sym)[actual_esym_index]; | 1473 | const global_sym = self.symbol(global_sym_index); |
| 1450 | global_esym.st_value = @intCast(elf_file.symbol(sym_index).value); | 1474 | global_sym.value = value; |
| | 1475 | global_sym.flags.weak = exp.opts.linkage == .weak; |
| | 1476 | global_sym.version_index = elf_file.default_version_index; |
| | 1477 | global_sym.ref = .{ .index = esym_shndx, .file = self.index }; |
| | 1478 | const global_esym = global_sym.elfSym(elf_file); |
| | 1479 | global_esym.st_value = @intCast(value); |
| 1451 | global_esym.st_shndx = esym.st_shndx; | 1480 | global_esym.st_shndx = esym.st_shndx; |
| 1452 | global_esym.st_info = (stb_bits << 4) | stt_bits; | 1481 | global_esym.st_info = (stb_bits << 4) | stt_bits; |
| 1453 | global_esym.st_name = name_off; | 1482 | global_esym.st_name = name_off; |
| 1454 | global_esym.st_size = esym.st_size; | 1483 | global_esym.st_size = esym.st_size; |
| 1455 | self.global_esyms.items(.shndx)[actual_esym_index] = esym_shndx; | 1484 | self.symtab.items(.shndx)[global_sym.esym_index] = esym_shndx; |
| 1456 | } | 1485 | } |
| 1457 | } | 1486 | } |
| 1458 | | 1487 | |
| ... | @@ -1506,16 +1535,19 @@ pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_n | ... | @@ -1506,16 +1535,19 @@ pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_n |
| 1506 | const off = try self.strtab.insert(gpa, name); | 1535 | const off = try self.strtab.insert(gpa, name); |
| 1507 | const lookup_gop = try self.globals_lookup.getOrPut(gpa, off); | 1536 | const lookup_gop = try self.globals_lookup.getOrPut(gpa, off); |
| 1508 | if (!lookup_gop.found_existing) { | 1537 | if (!lookup_gop.found_existing) { |
| 1509 | const esym_index = try self.addGlobalEsym(gpa); | 1538 | lookup_gop.value_ptr.* = try self.newSymbol(gpa, off); |
| 1510 | const esym = self.elfSym(esym_index); | | |
| 1511 | esym.st_name = off; | | |
| 1512 | lookup_gop.value_ptr.* = esym_index; | | |
| 1513 | const gop = try elf_file.getOrPutGlobal(name); | | |
| 1514 | try self.global_symbols.append(gpa, gop.index); | | |
| 1515 | } | 1539 | } |
| 1516 | return lookup_gop.value_ptr.*; | 1540 | return lookup_gop.value_ptr.*; |
| 1517 | } | 1541 | } |
| 1518 | | 1542 | |
| | 1543 | pub fn asFile(self: *ZigObject) File { |
| | 1544 | return .{ .zig_object = self }; |
| | 1545 | } |
| | 1546 | |
| | 1547 | fn addString(self: *ZigObject, allocator: Allocator, string: []const u8) !u32 { |
| | 1548 | return self.strtab.insert(allocator, string); |
| | 1549 | } |
| | 1550 | |
| 1519 | pub fn getString(self: ZigObject, off: u32) [:0]const u8 { | 1551 | pub fn getString(self: ZigObject, off: u32) [:0]const u8 { |
| 1520 | return self.strtab.getAssumeExists(off); | 1552 | return self.strtab.getAssumeExists(off); |
| 1521 | } | 1553 | } |
| ... | @@ -1586,6 +1618,73 @@ pub fn setAtomExtra(self: *ZigObject, index: u32, extra: Atom.Extra) void { | ... | @@ -1586,6 +1618,73 @@ pub fn setAtomExtra(self: *ZigObject, index: u32, extra: Atom.Extra) void { |
| 1586 | } | 1618 | } |
| 1587 | } | 1619 | } |
| 1588 | | 1620 | |
| | 1621 | inline fn isGlobal(index: Symbol.Index) bool { |
| | 1622 | return index & global_symbol_bit != 0; |
| | 1623 | } |
| | 1624 | |
| | 1625 | pub fn symbol(self: *ZigObject, index: Symbol.Index) *Symbol { |
| | 1626 | const actual_index = index & symbol_mask; |
| | 1627 | if (isGlobal(index)) return &self.symbols.items[self.global_symbols.items[actual_index]]; |
| | 1628 | return &self.symbols.items[self.local_symbols.items[actual_index]]; |
| | 1629 | } |
| | 1630 | |
| | 1631 | pub fn resolveSymbol(self: ZigObject, index: Symbol.Index, elf_file: *Elf) Elf.Ref { |
| | 1632 | if (isGlobal(index)) { |
| | 1633 | const resolv = self.symbols_resolver.items[index & symbol_mask]; |
| | 1634 | return elf_file.resolver.get(resolv).?; |
| | 1635 | } |
| | 1636 | return .{ .index = index, .file = self.index }; |
| | 1637 | } |
| | 1638 | |
| | 1639 | pub fn addSymbol(self: *ZigObject, allocator: Allocator) !Symbol.Index { |
| | 1640 | try self.symbols.ensureUnusedCapacity(allocator, 1); |
| | 1641 | const index: Symbol.Index = @intCast(self.symbols.items.len); |
| | 1642 | self.symbols.appendAssumeCapacity(.{ .file_index = self.index }); |
| | 1643 | return index; |
| | 1644 | } |
| | 1645 | |
| | 1646 | pub fn addSymbolExtra(self: *ZigObject, allocator: Allocator, extra: Symbol.Extra) !u32 { |
| | 1647 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| | 1648 | try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len); |
| | 1649 | return self.addSymbolExtraAssumeCapacity(extra); |
| | 1650 | } |
| | 1651 | |
| | 1652 | pub fn addSymbolExtraAssumeCapacity(self: *ZigObject, extra: Symbol.Extra) u32 { |
| | 1653 | const index = @as(u32, @intCast(self.symbols_extra.items.len)); |
| | 1654 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| | 1655 | inline for (fields) |field| { |
| | 1656 | self.symbols_extra.appendAssumeCapacity(switch (field.type) { |
| | 1657 | u32 => @field(extra, field.name), |
| | 1658 | else => @compileError("bad field type"), |
| | 1659 | }); |
| | 1660 | } |
| | 1661 | return index; |
| | 1662 | } |
| | 1663 | |
| | 1664 | pub fn symbolExtra(self: *ZigObject, index: u32) Symbol.Extra { |
| | 1665 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| | 1666 | var i: usize = index; |
| | 1667 | var result: Symbol.Extra = undefined; |
| | 1668 | inline for (fields) |field| { |
| | 1669 | @field(result, field.name) = switch (field.type) { |
| | 1670 | u32 => self.symbols_extra.items[i], |
| | 1671 | else => @compileError("bad field type"), |
| | 1672 | }; |
| | 1673 | i += 1; |
| | 1674 | } |
| | 1675 | return result; |
| | 1676 | } |
| | 1677 | |
| | 1678 | pub fn setSymbolExtra(self: *ZigObject, index: u32, extra: Symbol.Extra) void { |
| | 1679 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| | 1680 | inline for (fields, 0..) |field, i| { |
| | 1681 | self.symbols_extra.items[index + i] = switch (field.type) { |
| | 1682 | u32 => @field(extra, field.name), |
| | 1683 | else => @compileError("bad field type"), |
| | 1684 | }; |
| | 1685 | } |
| | 1686 | } |
| | 1687 | |
| 1589 | pub fn fmtSymtab(self: *ZigObject, elf_file: *Elf) std.fmt.Formatter(formatSymtab) { | 1688 | pub fn fmtSymtab(self: *ZigObject, elf_file: *Elf) std.fmt.Formatter(formatSymtab) { |
| 1590 | return .{ .data = .{ | 1689 | return .{ .data = .{ |
| 1591 | .self = self, | 1690 | .self = self, |
| ... | @@ -1658,9 +1757,9 @@ const DeclMetadata = struct { | ... | @@ -1658,9 +1757,9 @@ const DeclMetadata = struct { |
| 1658 | /// A list of all exports aliases of this Decl. | 1757 | /// A list of all exports aliases of this Decl. |
| 1659 | exports: std.ArrayListUnmanaged(Symbol.Index) = .{}, | 1758 | exports: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 1660 | | 1759 | |
| 1661 | fn @"export"(m: DeclMetadata, zig_object: *ZigObject, name: []const u8) ?*u32 { | 1760 | fn @"export"(m: DeclMetadata, zo: *ZigObject, name: []const u8) ?*u32 { |
| 1662 | for (m.exports.items) |*exp| { | 1761 | for (m.exports.items) |*exp| { |
| 1663 | const exp_name = zig_object.getString(zig_object.elfSym(exp.*).st_name); | 1762 | const exp_name = zo.getString(zo.symbol(exp.*).name_off); |
| 1664 | if (mem.eql(u8, name, exp_name)) return exp; | 1763 | if (mem.eql(u8, name, exp_name)) return exp; |
| 1665 | } | 1764 | } |
| 1666 | return null; | 1765 | return null; |