| ... | ... | @@ -17,7 +17,7 @@ shdr_table_offset: ?u64 = null, |
| 17 | 17 | |
| 18 | 18 | /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. |
| 19 | 19 | /// Same order as in the file. |
| 20 | | program_headers: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{}, |
| 20 | phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{}, |
| 21 | 21 | /// The index into the program headers of the PT_PHDR program header |
| 22 | 22 | phdr_table_index: ?u16 = null, |
| 23 | 23 | /// The index into the program headers of the PT_LOAD program header containing the phdr |
| ... | ... | @@ -232,7 +232,7 @@ pub fn deinit(self: *Elf) void { |
| 232 | 232 | } |
| 233 | 233 | self.sections.deinit(gpa); |
| 234 | 234 | |
| 235 | | self.program_headers.deinit(gpa); |
| 235 | self.phdrs.deinit(gpa); |
| 236 | 236 | self.shstrtab.deinit(gpa); |
| 237 | 237 | self.strtab.deinit(gpa); |
| 238 | 238 | self.symbols.deinit(gpa); |
| ... | ... | @@ -317,10 +317,10 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { |
| 317 | 317 | return test_end; |
| 318 | 318 | } |
| 319 | 319 | } |
| 320 | | for (self.program_headers.items) |program_header| { |
| 321 | | const increased_size = padToIdeal(program_header.p_filesz); |
| 322 | | const test_end = program_header.p_offset + increased_size; |
| 323 | | if (end > program_header.p_offset and start < test_end) { |
| 320 | for (self.phdrs.items) |phdr| { |
| 321 | const increased_size = padToIdeal(phdr.p_filesz); |
| 322 | const test_end = phdr.p_offset + increased_size; |
| 323 | if (end > phdr.p_offset and start < test_end) { |
| 324 | 324 | return test_end; |
| 325 | 325 | } |
| 326 | 326 | } |
| ... | ... | @@ -338,9 +338,9 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 { |
| 338 | 338 | if (section.sh_offset <= start) continue; |
| 339 | 339 | if (section.sh_offset < min_pos) min_pos = section.sh_offset; |
| 340 | 340 | } |
| 341 | | for (self.program_headers.items) |program_header| { |
| 342 | | if (program_header.p_offset <= start) continue; |
| 343 | | if (program_header.p_offset < min_pos) min_pos = program_header.p_offset; |
| 341 | for (self.phdrs.items) |phdr| { |
| 342 | if (phdr.p_offset <= start) continue; |
| 343 | if (phdr.p_offset < min_pos) min_pos = phdr.p_offset; |
| 344 | 344 | } |
| 345 | 345 | return min_pos - start; |
| 346 | 346 | } |
| ... | ... | @@ -364,12 +364,12 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 364 | 364 | const ptr_size: u8 = self.ptrWidthBytes(); |
| 365 | 365 | |
| 366 | 366 | if (self.phdr_table_index == null) { |
| 367 | | self.phdr_table_index = @as(u16, @intCast(self.program_headers.items.len)); |
| 367 | self.phdr_table_index = @as(u16, @intCast(self.phdrs.items.len)); |
| 368 | 368 | const p_align: u16 = switch (self.ptr_width) { |
| 369 | 369 | .p32 => @alignOf(elf.Elf32_Phdr), |
| 370 | 370 | .p64 => @alignOf(elf.Elf64_Phdr), |
| 371 | 371 | }; |
| 372 | | try self.program_headers.append(gpa, .{ |
| 372 | try self.phdrs.append(gpa, .{ |
| 373 | 373 | .p_type = elf.PT_PHDR, |
| 374 | 374 | .p_offset = 0, |
| 375 | 375 | .p_filesz = 0, |
| ... | ... | @@ -383,11 +383,11 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 383 | 383 | } |
| 384 | 384 | |
| 385 | 385 | if (self.phdr_table_load_index == null) { |
| 386 | | self.phdr_table_load_index = @as(u16, @intCast(self.program_headers.items.len)); |
| 386 | self.phdr_table_load_index = @as(u16, @intCast(self.phdrs.items.len)); |
| 387 | 387 | // TODO Same as for GOT |
| 388 | 388 | const phdr_addr: u64 = if (self.base.options.target.ptrBitWidth() >= 32) 0x1000000 else 0x1000; |
| 389 | 389 | const p_align = self.page_size; |
| 390 | | try self.program_headers.append(gpa, .{ |
| 390 | try self.phdrs.append(gpa, .{ |
| 391 | 391 | .p_type = elf.PT_LOAD, |
| 392 | 392 | .p_offset = 0, |
| 393 | 393 | .p_filesz = 0, |
| ... | ... | @@ -401,13 +401,13 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | 403 | if (self.phdr_load_re_index == null) { |
| 404 | | self.phdr_load_re_index = @as(u16, @intCast(self.program_headers.items.len)); |
| 404 | self.phdr_load_re_index = @as(u16, @intCast(self.phdrs.items.len)); |
| 405 | 405 | const file_size = self.base.options.program_code_size_hint; |
| 406 | 406 | const p_align = self.page_size; |
| 407 | 407 | const off = self.findFreeSpace(file_size, p_align); |
| 408 | 408 | log.debug("found PT_LOAD RE free space 0x{x} to 0x{x}", .{ off, off + file_size }); |
| 409 | 409 | const entry_addr: u64 = self.entry_addr orelse if (self.base.options.target.cpu.arch == .spu_2) @as(u64, 0) else default_entry_addr; |
| 410 | | try self.program_headers.append(gpa, .{ |
| 410 | try self.phdrs.append(gpa, .{ |
| 411 | 411 | .p_type = elf.PT_LOAD, |
| 412 | 412 | .p_offset = off, |
| 413 | 413 | .p_filesz = file_size, |
| ... | ... | @@ -422,7 +422,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 422 | 422 | } |
| 423 | 423 | |
| 424 | 424 | if (self.phdr_got_index == null) { |
| 425 | | self.phdr_got_index = @as(u16, @intCast(self.program_headers.items.len)); |
| 425 | self.phdr_got_index = @as(u16, @intCast(self.phdrs.items.len)); |
| 426 | 426 | const file_size = @as(u64, ptr_size) * self.base.options.symbol_count_hint; |
| 427 | 427 | // We really only need ptr alignment but since we are using PROGBITS, linux requires |
| 428 | 428 | // page align. |
| ... | ... | @@ -433,7 +433,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 433 | 433 | // we'll need to re-use that function anyway, in case the GOT grows and overlaps something |
| 434 | 434 | // else in virtual memory. |
| 435 | 435 | const got_addr: u32 = if (self.base.options.target.ptrBitWidth() >= 32) 0x4000000 else 0x8000; |
| 436 | | try self.program_headers.append(gpa, .{ |
| 436 | try self.phdrs.append(gpa, .{ |
| 437 | 437 | .p_type = elf.PT_LOAD, |
| 438 | 438 | .p_offset = off, |
| 439 | 439 | .p_filesz = file_size, |
| ... | ... | @@ -447,7 +447,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 447 | 447 | } |
| 448 | 448 | |
| 449 | 449 | if (self.phdr_load_ro_index == null) { |
| 450 | | self.phdr_load_ro_index = @as(u16, @intCast(self.program_headers.items.len)); |
| 450 | self.phdr_load_ro_index = @as(u16, @intCast(self.phdrs.items.len)); |
| 451 | 451 | // TODO Find a hint about how much data need to be in rodata ? |
| 452 | 452 | const file_size = 1024; |
| 453 | 453 | // Same reason as for GOT |
| ... | ... | @@ -456,7 +456,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 456 | 456 | log.debug("found PT_LOAD RO free space 0x{x} to 0x{x}", .{ off, off + file_size }); |
| 457 | 457 | // TODO Same as for GOT |
| 458 | 458 | const rodata_addr: u32 = if (self.base.options.target.ptrBitWidth() >= 32) 0xc000000 else 0xa000; |
| 459 | | try self.program_headers.append(gpa, .{ |
| 459 | try self.phdrs.append(gpa, .{ |
| 460 | 460 | .p_type = elf.PT_LOAD, |
| 461 | 461 | .p_offset = off, |
| 462 | 462 | .p_filesz = file_size, |
| ... | ... | @@ -470,7 +470,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 470 | 470 | } |
| 471 | 471 | |
| 472 | 472 | if (self.phdr_load_rw_index == null) { |
| 473 | | self.phdr_load_rw_index = @as(u16, @intCast(self.program_headers.items.len)); |
| 473 | self.phdr_load_rw_index = @as(u16, @intCast(self.phdrs.items.len)); |
| 474 | 474 | // TODO Find a hint about how much data need to be in data ? |
| 475 | 475 | const file_size = 1024; |
| 476 | 476 | // Same reason as for GOT |
| ... | ... | @@ -479,7 +479,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 479 | 479 | log.debug("found PT_LOAD RW free space 0x{x} to 0x{x}", .{ off, off + file_size }); |
| 480 | 480 | // TODO Same as for GOT |
| 481 | 481 | const rwdata_addr: u32 = if (self.base.options.target.ptrBitWidth() >= 32) 0x10000000 else 0xc000; |
| 482 | | try self.program_headers.append(gpa, .{ |
| 482 | try self.phdrs.append(gpa, .{ |
| 483 | 483 | .p_type = elf.PT_LOAD, |
| 484 | 484 | .p_offset = off, |
| 485 | 485 | .p_filesz = file_size, |
| ... | ... | @@ -544,7 +544,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 544 | 544 | |
| 545 | 545 | if (self.text_section_index == null) { |
| 546 | 546 | self.text_section_index = @as(u16, @intCast(self.sections.slice().len)); |
| 547 | | const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; |
| 547 | const phdr = &self.phdrs.items[self.phdr_load_re_index.?]; |
| 548 | 548 | |
| 549 | 549 | try self.sections.append(gpa, .{ |
| 550 | 550 | .shdr = .{ |
| ... | ... | @@ -566,7 +566,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 566 | 566 | |
| 567 | 567 | if (self.got_section_index == null) { |
| 568 | 568 | self.got_section_index = @as(u16, @intCast(self.sections.slice().len)); |
| 569 | | const phdr = &self.program_headers.items[self.phdr_got_index.?]; |
| 569 | const phdr = &self.phdrs.items[self.phdr_got_index.?]; |
| 570 | 570 | |
| 571 | 571 | try self.sections.append(gpa, .{ |
| 572 | 572 | .shdr = .{ |
| ... | ... | @@ -588,7 +588,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 588 | 588 | |
| 589 | 589 | if (self.rodata_section_index == null) { |
| 590 | 590 | self.rodata_section_index = @as(u16, @intCast(self.sections.slice().len)); |
| 591 | | const phdr = &self.program_headers.items[self.phdr_load_ro_index.?]; |
| 591 | const phdr = &self.phdrs.items[self.phdr_load_ro_index.?]; |
| 592 | 592 | |
| 593 | 593 | try self.sections.append(gpa, .{ |
| 594 | 594 | .shdr = .{ |
| ... | ... | @@ -610,7 +610,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 610 | 610 | |
| 611 | 611 | if (self.data_section_index == null) { |
| 612 | 612 | self.data_section_index = @as(u16, @intCast(self.sections.slice().len)); |
| 613 | | const phdr = &self.program_headers.items[self.phdr_load_rw_index.?]; |
| 613 | const phdr = &self.phdrs.items[self.phdr_load_rw_index.?]; |
| 614 | 614 | |
| 615 | 615 | try self.sections.append(gpa, .{ |
| 616 | 616 | .shdr = .{ |
| ... | ... | @@ -858,7 +858,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { |
| 858 | 858 | // TODO Also detect virtual address collisions. |
| 859 | 859 | const shdr = &self.sections.items(.shdr)[shdr_index]; |
| 860 | 860 | const phdr_index = self.sections.items(.phdr_index)[shdr_index]; |
| 861 | | const phdr = &self.program_headers.items[phdr_index]; |
| 861 | const phdr = &self.phdrs.items[phdr_index]; |
| 862 | 862 | const last_atom_index = self.sections.items(.last_atom_index)[shdr_index]; |
| 863 | 863 | |
| 864 | 864 | if (needed_size > self.allocatedSize(shdr.sh_offset)) { |
| ... | ... | @@ -1078,7 +1078,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1078 | 1078 | if (self.debug_info_header_dirty) { |
| 1079 | 1079 | // Currently only one compilation unit is supported, so the address range is simply |
| 1080 | 1080 | // identical to the main program header virtual address and memory size. |
| 1081 | | const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; |
| 1081 | const text_phdr = &self.phdrs.items[self.phdr_load_re_index.?]; |
| 1082 | 1082 | const low_pc = text_phdr.p_vaddr; |
| 1083 | 1083 | const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; |
| 1084 | 1084 | try dw.writeDbgInfoHeader(module, low_pc, high_pc); |
| ... | ... | @@ -1088,7 +1088,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1088 | 1088 | if (self.debug_aranges_section_dirty) { |
| 1089 | 1089 | // Currently only one compilation unit is supported, so the address range is simply |
| 1090 | 1090 | // identical to the main program header virtual address and memory size. |
| 1091 | | const text_phdr = &self.program_headers.items[self.phdr_load_re_index.?]; |
| 1091 | const text_phdr = &self.phdrs.items[self.phdr_load_re_index.?]; |
| 1092 | 1092 | try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz); |
| 1093 | 1093 | if (!self.shdr_table_dirty) { |
| 1094 | 1094 | // Then it won't get written with the others and we need to do it. |
| ... | ... | @@ -1110,11 +1110,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1110 | 1110 | }; |
| 1111 | 1111 | |
| 1112 | 1112 | const phdr_table_index = self.phdr_table_index.?; |
| 1113 | | const phdr_table = &self.program_headers.items[phdr_table_index]; |
| 1114 | | const phdr_table_load = &self.program_headers.items[self.phdr_table_load_index.?]; |
| 1113 | const phdr_table = &self.phdrs.items[phdr_table_index]; |
| 1114 | const phdr_table_load = &self.phdrs.items[self.phdr_table_load_index.?]; |
| 1115 | 1115 | |
| 1116 | 1116 | const allocated_size = self.allocatedSize(phdr_table.p_offset); |
| 1117 | | const needed_size = self.program_headers.items.len * phsize; |
| 1117 | const needed_size = self.phdrs.items.len * phsize; |
| 1118 | 1118 | |
| 1119 | 1119 | if (needed_size > allocated_size) { |
| 1120 | 1120 | phdr_table.p_offset = 0; // free the space |
| ... | ... | @@ -1133,11 +1133,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1133 | 1133 | |
| 1134 | 1134 | switch (self.ptr_width) { |
| 1135 | 1135 | .p32 => { |
| 1136 | | const buf = try gpa.alloc(elf.Elf32_Phdr, self.program_headers.items.len); |
| 1136 | const buf = try gpa.alloc(elf.Elf32_Phdr, self.phdrs.items.len); |
| 1137 | 1137 | defer gpa.free(buf); |
| 1138 | 1138 | |
| 1139 | 1139 | for (buf, 0..) |*phdr, i| { |
| 1140 | | phdr.* = progHeaderTo32(self.program_headers.items[i]); |
| 1140 | phdr.* = progHeaderTo32(self.phdrs.items[i]); |
| 1141 | 1141 | if (foreign_endian) { |
| 1142 | 1142 | mem.byteSwapAllFields(elf.Elf32_Phdr, phdr); |
| 1143 | 1143 | } |
| ... | ... | @@ -1145,11 +1145,11 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1145 | 1145 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); |
| 1146 | 1146 | }, |
| 1147 | 1147 | .p64 => { |
| 1148 | | const buf = try gpa.alloc(elf.Elf64_Phdr, self.program_headers.items.len); |
| 1148 | const buf = try gpa.alloc(elf.Elf64_Phdr, self.phdrs.items.len); |
| 1149 | 1149 | defer gpa.free(buf); |
| 1150 | 1150 | |
| 1151 | 1151 | for (buf, 0..) |*phdr, i| { |
| 1152 | | phdr.* = self.program_headers.items[i]; |
| 1152 | phdr.* = self.phdrs.items[i]; |
| 1153 | 1153 | if (foreign_endian) { |
| 1154 | 1154 | mem.byteSwapAllFields(elf.Elf64_Phdr, phdr); |
| 1155 | 1155 | } |
| ... | ... | @@ -2018,7 +2018,7 @@ fn writeElfHeader(self: *Elf) !void { |
| 2018 | 2018 | |
| 2019 | 2019 | const e_entry = if (elf_type == .REL) 0 else self.entry_addr.?; |
| 2020 | 2020 | |
| 2021 | | const phdr_table_offset = self.program_headers.items[self.phdr_table_index.?].p_offset; |
| 2021 | const phdr_table_offset = self.phdrs.items[self.phdr_table_index.?].p_offset; |
| 2022 | 2022 | switch (self.ptr_width) { |
| 2023 | 2023 | .p32 => { |
| 2024 | 2024 | mem.writeInt(u32, hdr_buf[index..][0..4], @as(u32, @intCast(e_entry)), endian); |
| ... | ... | @@ -2065,7 +2065,7 @@ fn writeElfHeader(self: *Elf) !void { |
| 2065 | 2065 | mem.writeInt(u16, hdr_buf[index..][0..2], e_phentsize, endian); |
| 2066 | 2066 | index += 2; |
| 2067 | 2067 | |
| 2068 | | const e_phnum = @as(u16, @intCast(self.program_headers.items.len)); |
| 2068 | const e_phnum = @as(u16, @intCast(self.phdrs.items.len)); |
| 2069 | 2069 | mem.writeInt(u16, hdr_buf[index..][0..2], e_phnum, endian); |
| 2070 | 2070 | index += 2; |
| 2071 | 2071 | |
| ... | ... | @@ -2264,7 +2264,7 @@ fn updateDeclCode( |
| 2264 | 2264 | } |
| 2265 | 2265 | |
| 2266 | 2266 | const phdr_index = self.sections.items(.phdr_index)[shdr_index]; |
| 2267 | | const section_offset = sym.value - self.program_headers.items[phdr_index].p_vaddr; |
| 2267 | const section_offset = sym.value - self.phdrs.items[phdr_index].p_vaddr; |
| 2268 | 2268 | const file_offset = self.sections.items(.shdr)[shdr_index].sh_offset + section_offset; |
| 2269 | 2269 | |
| 2270 | 2270 | if (self.base.child_pid) |pid| { |
| ... | ... | @@ -2494,7 +2494,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol. |
| 2494 | 2494 | const got_index = try local_sym.getOrCreateGotEntry(self); |
| 2495 | 2495 | try self.got.writeEntry(self, got_index); |
| 2496 | 2496 | |
| 2497 | | const section_offset = atom_ptr.value - self.program_headers.items[phdr_index].p_vaddr; |
| 2497 | const section_offset = atom_ptr.value - self.phdrs.items[phdr_index].p_vaddr; |
| 2498 | 2498 | const file_offset = self.sections.items(.shdr)[local_sym.output_section_index].sh_offset + section_offset; |
| 2499 | 2499 | try self.base.file.?.pwriteAll(code, file_offset); |
| 2500 | 2500 | } |
| ... | ... | @@ -2564,7 +2564,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module |
| 2564 | 2564 | |
| 2565 | 2565 | try unnamed_consts.append(gpa, atom_ptr.atom_index); |
| 2566 | 2566 | |
| 2567 | | const section_offset = atom_ptr.value - self.program_headers.items[phdr_index].p_vaddr; |
| 2567 | const section_offset = atom_ptr.value - self.phdrs.items[phdr_index].p_vaddr; |
| 2568 | 2568 | const file_offset = self.sections.items(.shdr)[shdr_index].sh_offset + section_offset; |
| 2569 | 2569 | try self.base.file.?.pwriteAll(code, file_offset); |
| 2570 | 2570 | |
| ... | ... | @@ -2684,17 +2684,17 @@ pub fn deleteDeclExport( |
| 2684 | 2684 | |
| 2685 | 2685 | fn writeProgHeader(self: *Elf, index: usize) !void { |
| 2686 | 2686 | const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian(); |
| 2687 | | const offset = self.program_headers.items[index].p_offset; |
| 2687 | const offset = self.phdrs.items[index].p_offset; |
| 2688 | 2688 | switch (self.ptr_width) { |
| 2689 | 2689 | .p32 => { |
| 2690 | | var phdr = [1]elf.Elf32_Phdr{progHeaderTo32(self.program_headers.items[index])}; |
| 2690 | var phdr = [1]elf.Elf32_Phdr{progHeaderTo32(self.phdrs.items[index])}; |
| 2691 | 2691 | if (foreign_endian) { |
| 2692 | 2692 | mem.byteSwapAllFields(elf.Elf32_Phdr, &phdr[0]); |
| 2693 | 2693 | } |
| 2694 | 2694 | return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset); |
| 2695 | 2695 | }, |
| 2696 | 2696 | .p64 => { |
| 2697 | | var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]}; |
| 2697 | var phdr = [1]elf.Elf64_Phdr{self.phdrs.items[index]}; |
| 2698 | 2698 | if (foreign_endian) { |
| 2699 | 2699 | mem.byteSwapAllFields(elf.Elf64_Phdr, &phdr[0]); |
| 2700 | 2700 | } |