| ... | @@ -328,7 +328,9 @@ fn initSubsections(self: *Object, allocator: Allocator, nlists: anytype) !void { | ... | @@ -328,7 +328,9 @@ fn initSubsections(self: *Object, allocator: Allocator, nlists: anytype) !void { |
| 328 | if (isPtrLiteral(sect)) continue; | 328 | if (isPtrLiteral(sect)) continue; |
| 329 | | 329 | |
| 330 | const nlist_start = for (nlists, 0..) |nlist, i| { | 330 | const nlist_start = for (nlists, 0..) |nlist, i| { |
| 331 | if (nlist.nlist.n_sect - 1 == n_sect) break i; | 331 | // We must ignore `alt_entry` (N_ALT_ENTRY) symbols here, because that flag indicates |
| | 332 | // that a symbol should *not* split subsections. |
| | 333 | if (nlist.nlist.n_sect - 1 == n_sect and !nlist.nlist.n_desc.alt_entry) break i; |
| 332 | } else nlists.len; | 334 | } else nlists.len; |
| 333 | const nlist_end = for (nlists[nlist_start..], nlist_start..) |nlist, i| { | 335 | const nlist_end = for (nlists[nlist_start..], nlist_start..) |nlist, i| { |
| 334 | if (nlist.nlist.n_sect - 1 != n_sect) break i; | 336 | if (nlist.nlist.n_sect - 1 != n_sect) break i; |
| ... | @@ -359,9 +361,24 @@ fn initSubsections(self: *Object, allocator: Allocator, nlists: anytype) !void { | ... | @@ -359,9 +361,24 @@ fn initSubsections(self: *Object, allocator: Allocator, nlists: anytype) !void { |
| 359 | const alias_start = idx; | 361 | const alias_start = idx; |
| 360 | const nlist = nlists[alias_start]; | 362 | const nlist = nlists[alias_start]; |
| 361 | | 363 | |
| 362 | while (idx < nlist_end and | 364 | // Skip past any symbols which shouldn't terminate this subsection. |
| 363 | nlists[idx].nlist.n_value == nlist.nlist.n_value) : (idx += 1) | 365 | while (true) { |
| 364 | {} | 366 | idx += 1; |
| | 367 | if (idx == nlist_end) { |
| | 368 | // This subsection contains the full remainder of the section. |
| | 369 | break; |
| | 370 | } |
| | 371 | if (nlists[idx].nlist.n_value == nlist.nlist.n_value) { |
| | 372 | // Multiple symbols at the same address---don't create zero-length subsections. |
| | 373 | continue; |
| | 374 | } |
| | 375 | if (nlists[idx].nlist.n_desc.alt_entry) { |
| | 376 | // N_ALT_ENTRY indicates that this symbol does not split subsections, and is |
| | 377 | // instead an "alternate entry point" into an existing subsection. |
| | 378 | continue; |
| | 379 | } |
| | 380 | break; |
| | 381 | } |
| 365 | | 382 | |
| 366 | const size = if (idx < nlist_end) | 383 | const size = if (idx < nlist_end) |
| 367 | nlists[idx].nlist.n_value - nlist.nlist.n_value | 384 | nlists[idx].nlist.n_value - nlist.nlist.n_value |
| ... | @@ -385,7 +402,9 @@ fn initSubsections(self: *Object, allocator: Allocator, nlists: anytype) !void { | ... | @@ -385,7 +402,9 @@ fn initSubsections(self: *Object, allocator: Allocator, nlists: anytype) !void { |
| 385 | }); | 402 | }); |
| 386 | | 403 | |
| 387 | for (alias_start..idx) |i| { | 404 | for (alias_start..idx) |i| { |
| 388 | self.symtab.items(.size)[nlists[i].idx] = size; | 405 | if (!nlists[i].nlist.n_desc.alt_entry) { |
| | 406 | self.symtab.items(.size)[nlists[i].idx] = size; |
| | 407 | } |
| 389 | } | 408 | } |
| 390 | } | 409 | } |
| 391 | | 410 | |