@@ -60,7 +60,7 @@ symbols_extra: std.ArrayListUnmanaged(u32) = .{},
60
60
globals : std .AutoHashMapUnmanaged (u32 , Symbol .Index ) = .{},
61
61
/// This table will be populated after `scanRelocs` has run.
62
62
/// Key is symbol index.
63
- undefs : std .AutoHashMapUnmanaged (Symbol.Index , std .ArrayListUnmanaged (Atom . Index )) = .{},
63
+ undefs : std .AutoHashMapUnmanaged (Symbol.Index , std .ArrayListUnmanaged (Ref )) = .{},
64
64
65
65
string_intern : StringTable = .{},
66
66
@@ -84,8 +84,6 @@ rela_dyn: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{},
84
84
rela_plt : std .ArrayListUnmanaged (elf .Elf64_Rela ) = .{},
85
85
comdat_group_sections : std .ArrayListUnmanaged (ComdatGroupSection ) = .{},
86
86
87
- atoms : std .ArrayListUnmanaged (Atom ) = .{},
88
- atoms_extra : std .ArrayListUnmanaged (u32 ) = .{},
89
87
thunks : std .ArrayListUnmanaged (Thunk ) = .{},
90
88
91
89
merge_sections : std .ArrayListUnmanaged (MergeSection ) = .{},
@@ -139,8 +137,6 @@ pub fn deinit(self: *Elf) void {
139
137
self .shstrtab .deinit (gpa );
140
138
self .symtab .deinit (gpa );
141
139
self .strtab .deinit (gpa );
142
- self .atoms .deinit (gpa );
143
- self .atoms_extra .deinit (gpa );
144
140
for (self .thunks .items ) | * thunk | {
145
141
thunk .deinit (gpa );
146
142
}
@@ -275,9 +271,6 @@ pub fn flush(self: *Elf) !void {
275
271
try self .dynstrtab .buffer .append (gpa , 0 );
276
272
// Append null section.
277
273
_ = try self .addSection (.{ .name = "" });
278
- // Append null atom.
279
- try self .atoms .append (gpa , .{});
280
- try self .atoms_extra .append (gpa , 0 );
281
274
// Append null symbols.
282
275
try self .symtab .append (gpa , null_sym );
283
276
try self .symbols .append (gpa , .{});
@@ -456,11 +449,11 @@ fn sortInitFini(self: *Elf) !void {
456
449
457
450
const Entry = struct {
458
451
priority : i32 ,
459
- atom_index : Atom.Index ,
452
+ atom_ref : Elf.Ref ,
460
453
461
454
pub fn lessThan (ctx : * Elf , lhs : @This (), rhs : @This ()) bool {
462
455
if (lhs .priority == rhs .priority ) {
463
- return ctx .getAtom (lhs .atom_index ).? .getPriority (ctx ) < ctx .getAtom (rhs .atom_index ).? .getPriority (ctx );
456
+ return ctx .getAtom (lhs .atom_ref ).? .getPriority (ctx ) < ctx .getAtom (rhs .atom_ref ).? .getPriority (ctx );
464
457
}
465
458
return lhs .priority < rhs .priority ;
466
459
}
@@ -490,8 +483,8 @@ fn sortInitFini(self: *Elf) !void {
490
483
try entries .ensureTotalCapacityPrecise (atoms .items .len );
491
484
defer entries .deinit ();
492
485
493
- for (atoms .items ) | atom_index | {
494
- const atom = self .getAtom (atom_index ).? ;
486
+ for (atoms .items ) | ref | {
487
+ const atom = self .getAtom (ref ).? ;
495
488
const file = atom .getObject (self );
496
489
const priority = blk : {
497
490
if (is_ctor_dtor ) {
@@ -504,23 +497,23 @@ fn sortInitFini(self: *Elf) !void {
504
497
const priority = std .fmt .parseUnsigned (u16 , it .first (), 10 ) catch default ;
505
498
break :blk priority ;
506
499
};
507
- entries .appendAssumeCapacity (.{ .priority = priority , .atom_index = atom_index });
500
+ entries .appendAssumeCapacity (.{ .priority = priority , .atom_ref = ref });
508
501
}
509
502
510
503
mem .sort (Entry , entries .items , self , Entry .lessThan );
511
504
512
505
atoms .clearRetainingCapacity ();
513
506
for (entries .items ) | entry | {
514
- atoms .appendAssumeCapacity (entry .atom_index );
507
+ atoms .appendAssumeCapacity (entry .atom_ref );
515
508
}
516
509
}
517
510
}
518
511
519
512
fn initOutputSections (self : * Elf ) ! void {
520
513
for (self .objects .items ) | index | {
521
514
const object = self .getFile (index ).? .object ;
522
- for (object .atoms .items ) | atom_index | {
523
- const atom = self .getAtom (atom_index ) orelse continue ;
515
+ for (object .atoms_indexes .items ) | atom_index | {
516
+ const atom = object .getAtom (atom_index ) orelse continue ;
524
517
if (! atom .flags .alive ) continue ;
525
518
atom .out_shndx = try object .initOutputSection (self , atom .getInputShdr (self ));
526
519
}
@@ -746,11 +739,14 @@ pub fn initShStrtab(self: *Elf) !void {
746
739
pub fn addAtomsToSections (self : * Elf ) ! void {
747
740
for (self .objects .items ) | index | {
748
741
const object = self .getFile (index ).? .object ;
749
- for (object .atoms .items ) | atom_index | {
750
- const atom = self .getAtom (atom_index ) orelse continue ;
742
+ for (object .atoms_indexes .items ) | atom_index | {
743
+ const atom = object .getAtom (atom_index ) orelse continue ;
751
744
if (! atom .flags .alive ) continue ;
752
745
const atoms = & self .sections .items (.atoms )[atom .out_shndx ];
753
- try atoms .append (self .base .allocator , atom_index );
746
+ try atoms .append (self .base .allocator , .{
747
+ .index = atom_index ,
748
+ .file = index ,
749
+ });
754
750
}
755
751
756
752
for (object .getLocals ()) | local_index | {
@@ -835,8 +831,8 @@ fn calcSectionSizes(self: *Elf) !void {
835
831
if (atoms .items .len == 0 ) continue ;
836
832
if (self .requiresThunks () and shdr .sh_flags & elf .SHF_EXECINSTR != 0 ) continue ;
837
833
838
- for (atoms .items ) | atom_index | {
839
- const atom = self .getAtom (atom_index ).? ;
834
+ for (atoms .items ) | ref | {
835
+ const atom = self .getAtom (ref ).? ;
840
836
const alignment = try math .powi (u64 , 2 , atom .alignment );
841
837
const offset = mem .alignForward (u64 , shdr .sh_size , alignment );
842
838
const padding = offset - shdr .sh_size ;
@@ -1551,8 +1547,9 @@ pub fn sortSections(self: *Elf) !void {
1551
1547
}
1552
1548
1553
1549
for (self .objects .items ) | index | {
1554
- for (self .getFile (index ).? .object .atoms .items ) | atom_index | {
1555
- const atom = self .getAtom (atom_index ) orelse continue ;
1550
+ const object = self .getFile (index ).? .object ;
1551
+ for (object .atoms_indexes .items ) | atom_index | {
1552
+ const atom = object .getAtom (atom_index ) orelse continue ;
1556
1553
if (! atom .flags .alive ) continue ;
1557
1554
atom .out_shndx = backlinks [atom .out_shndx ];
1558
1555
}
@@ -2084,8 +2081,8 @@ fn markEhFrameAtomsDead(self: *Elf) void {
2084
2081
const file = self .getFile (index ).? ;
2085
2082
if (! file .isAlive ()) continue ;
2086
2083
const object = file .object ;
2087
- for (object .atoms .items ) | atom_index | {
2088
- const atom = self .getAtom (atom_index ) orelse continue ;
2084
+ for (object .atoms_indexes .items ) | atom_index | {
2085
+ const atom = object .getAtom (atom_index ) orelse continue ;
2089
2086
const is_eh_frame = (self .options .cpu_arch .? == .x86_64 and atom .getInputShdr (self ).sh_type == elf .SHT_X86_64_UNWIND ) or
2090
2087
mem .eql (u8 , atom .getName (self ), ".eh_frame" );
2091
2088
if (atom .flags .alive and is_eh_frame ) atom .flags .alive = false ;
@@ -2234,7 +2231,7 @@ fn claimUnresolved(self: *Elf) void {
2234
2231
};
2235
2232
2236
2233
global .value = 0 ;
2237
- global .atom = 0 ;
2234
+ global .atom_ref = .{} ;
2238
2235
global .sym_idx = sym_idx ;
2239
2236
global .file = object .index ;
2240
2237
global .ver_idx = if (is_import ) elf .VER_NDX_LOCAL else self .default_sym_version ;
@@ -2403,12 +2400,12 @@ fn writeAtoms(self: *Elf) !void {
2403
2400
2404
2401
var stream = std .io .fixedBufferStream (buffer );
2405
2402
2406
- for (atoms .items ) | atom_index | {
2407
- const atom = self .getAtom (atom_index ).? ;
2403
+ for (atoms .items ) | ref | {
2404
+ const atom = self .getAtom (ref ).? ;
2408
2405
assert (atom .flags .alive );
2409
2406
const off : u64 = @intCast (atom .value );
2410
- log .debug ("writing ATOM(%{d },'{s}') at offset 0x{x}" , .{
2411
- atom_index ,
2407
+ log .debug ("writing ATOM({ },'{s}') at offset 0x{x}" , .{
2408
+ ref ,
2412
2409
atom .getName (self ),
2413
2410
shdr .sh_offset + off ,
2414
2411
});
@@ -2733,63 +2730,6 @@ pub fn getFileHandle(self: Elf, index: File.HandleIndex) File.Handle {
2733
2730
return self .file_handles .items [index ];
2734
2731
}
2735
2732
2736
- pub fn addAtom (self : * Elf ) ! Atom.Index {
2737
- const index = @as (u32 , @intCast (self .atoms .items .len ));
2738
- const atom = try self .atoms .addOne (self .base .allocator );
2739
- atom .* = .{};
2740
- return index ;
2741
- }
2742
-
2743
- pub fn getAtom (self : Elf , atom_index : Atom.Index ) ? * Atom {
2744
- if (atom_index == 0 ) return null ;
2745
- assert (atom_index < self .atoms .items .len );
2746
- return & self .atoms .items [atom_index ];
2747
- }
2748
-
2749
- pub fn addAtomExtra (self : * Elf , extra : Atom.Extra ) ! u32 {
2750
- const fields = @typeInfo (Atom .Extra ).@"struct" .fields ;
2751
- try self .atoms_extra .ensureUnusedCapacity (self .base .allocator , fields .len );
2752
- return self .addAtomExtraAssumeCapacity (extra );
2753
- }
2754
-
2755
- pub fn addAtomExtraAssumeCapacity (self : * Elf , extra : Atom.Extra ) u32 {
2756
- const index = @as (u32 , @intCast (self .atoms_extra .items .len ));
2757
- const fields = @typeInfo (Atom .Extra ).@"struct" .fields ;
2758
- inline for (fields ) | field | {
2759
- self .atoms_extra .appendAssumeCapacity (switch (field .type ) {
2760
- u32 = > @field (extra , field .name ),
2761
- else = > @compileError ("bad field type" ),
2762
- });
2763
- }
2764
- return index ;
2765
- }
2766
-
2767
- pub fn getAtomExtra (self : * Elf , index : u32 ) ? Atom.Extra {
2768
- if (index == 0 ) return null ;
2769
- const fields = @typeInfo (Atom .Extra ).@"struct" .fields ;
2770
- var i : usize = index ;
2771
- var result : Atom.Extra = undefined ;
2772
- inline for (fields ) | field | {
2773
- @field (result , field .name ) = switch (field .type ) {
2774
- u32 = > self .atoms_extra .items [i ],
2775
- else = > @compileError ("bad field type" ),
2776
- };
2777
- i += 1 ;
2778
- }
2779
- return result ;
2780
- }
2781
-
2782
- pub fn setAtomExtra (self : * Elf , index : u32 , extra : Atom.Extra ) void {
2783
- assert (index > 0 );
2784
- const fields = @typeInfo (Atom .Extra ).@"struct" .fields ;
2785
- inline for (fields , 0.. ) | field , i | {
2786
- self .atoms_extra .items [index + i ] = switch (field .type ) {
2787
- u32 = > @field (extra , field .name ),
2788
- else = > @compileError ("bad field type" ),
2789
- };
2790
- }
2791
- }
2792
-
2793
2733
fn addThunk (self : * Elf ) ! Thunk.Index {
2794
2734
const index = @as (Thunk .Index , @intCast (self .thunks .items .len ));
2795
2735
const thunk = try self .thunks .addOne (self .base .allocator );
@@ -2821,8 +2761,8 @@ fn createThunks(self: *Elf, shndx: u32) !void {
2821
2761
const atoms = slice .items (.atoms )[shndx ].items ;
2822
2762
assert (atoms .len > 0 );
2823
2763
2824
- for (atoms ) | atom_index | {
2825
- self .getAtom (atom_index ).? .value = -1 ;
2764
+ for (atoms ) | ref | {
2765
+ self .getAtom (ref ).? .value = -1 ;
2826
2766
}
2827
2767
2828
2768
var i : usize = 0 ;
@@ -2834,8 +2774,8 @@ fn createThunks(self: *Elf, shndx: u32) !void {
2834
2774
i += 1 ;
2835
2775
2836
2776
while (i < atoms .len ) : (i += 1 ) {
2837
- const atom_index = atoms [i ];
2838
- const atom = self .getAtom (atom_index ).? ;
2777
+ const ref = atoms [i ];
2778
+ const atom = self .getAtom (ref ).? ;
2839
2779
assert (atom .flags .alive );
2840
2780
const alignment = try math .powi (u32 , 2 , atom .alignment );
2841
2781
if (@as (i64 , @intCast (mem .alignForward (u64 , shdr .sh_size , alignment ))) - start_atom .value >= Thunk .maxAllowedDistance (cpu_arch )) break ;
@@ -2848,16 +2788,16 @@ fn createThunks(self: *Elf, shndx: u32) !void {
2848
2788
thunk .out_shndx = shndx ;
2849
2789
2850
2790
// Scan relocs in the group and create trampolines for any unreachable callsite
2851
- for (atoms [start .. i ]) | atom_index | {
2852
- const atom = self .getAtom (atom_index ).? ;
2791
+ for (atoms [start .. i ]) | ref | {
2792
+ const atom = self .getAtom (ref ).? ;
2853
2793
const object = atom .getObject (self );
2854
- log .debug ("atom({d }) {s}" , .{ atom_index , atom .getName (self ) });
2794
+ log .debug ("atom({}) {s}" , .{ ref , atom .getName (self ) });
2855
2795
for (atom .getRelocs (self )) | rel | {
2856
2796
if (Thunk .isReachable (atom , rel , self )) continue ;
2857
2797
const target = object .symbols .items [rel .r_sym ()];
2858
2798
try thunk .symbols .put (gpa , target , {});
2859
2799
}
2860
- try atom .addExtra (.{ .thunk = thunk_index }, self );
2800
+ atom .addExtra (.{ .thunk = thunk_index }, self );
2861
2801
atom .flags .thunk = true ;
2862
2802
}
2863
2803
@@ -2995,6 +2935,10 @@ pub fn getMergeSection(self: *Elf, index: MergeSection.Index) *MergeSection {
2995
2935
return & self .merge_sections .items [index ];
2996
2936
}
2997
2937
2938
+ pub fn getAtom (self : * Elf , ref : Ref ) ? * Atom {
2939
+ return self .getFile (ref .file ).? .getAtom (ref .index );
2940
+ }
2941
+
2998
2942
pub fn getComdatGroup (self : * Elf , ref : Ref ) * ComdatGroup {
2999
2943
return self .getFile (ref .file ).? .getComdatGroup (ref .index );
3000
2944
}
@@ -3257,7 +3201,7 @@ pub const LinkObject = struct {
3257
3201
3258
3202
const Section = struct {
3259
3203
shdr : elf.Elf64_Shdr ,
3260
- atoms : std .ArrayListUnmanaged (Atom . Index ) = .{},
3204
+ atoms : std .ArrayListUnmanaged (Ref ) = .{},
3261
3205
rela_shndx : u32 = 0 ,
3262
3206
sym_index : u32 = 0 ,
3263
3207
};
0 commit comments