| ... | @@ -332,61 +332,6 @@ const Update = struct { | ... | @@ -332,61 +332,6 @@ const Update = struct { |
| 332 | phdr_table_dirty = true; | 332 | phdr_table_dirty = true; |
| 333 | } | 333 | } |
| 334 | const foreign_endian = self.module.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); | 334 | const foreign_endian = self.module.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); |
| 335 | if (phdr_table_dirty) { | | |
| 336 | const allocated_size = self.allocatedSize(self.phdr_table_offset.?); | | |
| 337 | const needed_size = self.program_headers.items.len * phsize; | | |
| 338 | | | |
| 339 | if (needed_size > allocated_size) { | | |
| 340 | self.phdr_table_offset = null; // free the space | | |
| 341 | self.phdr_table_offset = self.findFreeSpace(needed_size, phalign); | | |
| 342 | } | | |
| 343 | | | |
| 344 | const allocator = self.program_headers.allocator; | | |
| 345 | switch (ptr_width) { | | |
| 346 | .p32 => { | | |
| 347 | const buf = try allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len); | | |
| 348 | defer allocator.free(buf); | | |
| 349 | | | |
| 350 | for (buf) |*phdr, i| { | | |
| 351 | phdr.* = .{ | | |
| 352 | .p_type = self.program_headers.items[i].p_type, | | |
| 353 | .p_flags = self.program_headers.items[i].p_flags, | | |
| 354 | .p_offset = @intCast(u32, self.program_headers.items[i].p_offset), | | |
| 355 | .p_vaddr = @intCast(u32, self.program_headers.items[i].p_vaddr), | | |
| 356 | .p_paddr = @intCast(u32, self.program_headers.items[i].p_paddr), | | |
| 357 | .p_filesz = @intCast(u32, self.program_headers.items[i].p_filesz), | | |
| 358 | .p_memsz = @intCast(u32, self.program_headers.items[i].p_memsz), | | |
| 359 | .p_align = @intCast(u32, self.program_headers.items[i].p_align), | | |
| 360 | }; | | |
| 361 | if (foreign_endian) { | | |
| 362 | bswapAllFields(elf.Elf32_Phdr, phdr); | | |
| 363 | } | | |
| 364 | } | | |
| 365 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); | | |
| 366 | }, | | |
| 367 | .p64 => { | | |
| 368 | const buf = try allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len); | | |
| 369 | defer allocator.free(buf); | | |
| 370 | | | |
| 371 | for (buf) |*phdr, i| { | | |
| 372 | phdr.* = .{ | | |
| 373 | .p_type = self.program_headers.items[i].p_type, | | |
| 374 | .p_flags = self.program_headers.items[i].p_flags, | | |
| 375 | .p_offset = self.program_headers.items[i].p_offset, | | |
| 376 | .p_vaddr = self.program_headers.items[i].p_vaddr, | | |
| 377 | .p_paddr = self.program_headers.items[i].p_paddr, | | |
| 378 | .p_filesz = self.program_headers.items[i].p_filesz, | | |
| 379 | .p_memsz = self.program_headers.items[i].p_memsz, | | |
| 380 | .p_align = self.program_headers.items[i].p_align, | | |
| 381 | }; | | |
| 382 | if (foreign_endian) { | | |
| 383 | bswapAllFields(elf.Elf64_Phdr, phdr); | | |
| 384 | } | | |
| 385 | } | | |
| 386 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); | | |
| 387 | }, | | |
| 388 | } | | |
| 389 | } | | |
| 390 | if (shdr_table_dirty) { | 335 | if (shdr_table_dirty) { |
| 391 | const allocated_size = self.allocatedSize(self.shdr_table_offset.?); | 336 | const allocated_size = self.allocatedSize(self.shdr_table_offset.?); |
| 392 | const needed_size = self.sections.items.len * phsize; | 337 | const needed_size = self.sections.items.len * phsize; |
| ... | @@ -446,7 +391,64 @@ const Update = struct { | ... | @@ -446,7 +391,64 @@ const Update = struct { |
| 446 | }, | 391 | }, |
| 447 | } | 392 | } |
| 448 | } | 393 | } |
| 449 | try self.writeCodeAndSymbols(); | 394 | |
| | 395 | try self.writeCodeAndSymbols(&phdr_table_dirty); |
| | 396 | |
| | 397 | if (phdr_table_dirty) { |
| | 398 | const allocated_size = self.allocatedSize(self.phdr_table_offset.?); |
| | 399 | const needed_size = self.program_headers.items.len * phsize; |
| | 400 | |
| | 401 | if (needed_size > allocated_size) { |
| | 402 | self.phdr_table_offset = null; // free the space |
| | 403 | self.phdr_table_offset = self.findFreeSpace(needed_size, phalign); |
| | 404 | } |
| | 405 | |
| | 406 | const allocator = self.program_headers.allocator; |
| | 407 | switch (ptr_width) { |
| | 408 | .p32 => { |
| | 409 | const buf = try allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len); |
| | 410 | defer allocator.free(buf); |
| | 411 | |
| | 412 | for (buf) |*phdr, i| { |
| | 413 | phdr.* = .{ |
| | 414 | .p_type = self.program_headers.items[i].p_type, |
| | 415 | .p_flags = self.program_headers.items[i].p_flags, |
| | 416 | .p_offset = @intCast(u32, self.program_headers.items[i].p_offset), |
| | 417 | .p_vaddr = @intCast(u32, self.program_headers.items[i].p_vaddr), |
| | 418 | .p_paddr = @intCast(u32, self.program_headers.items[i].p_paddr), |
| | 419 | .p_filesz = @intCast(u32, self.program_headers.items[i].p_filesz), |
| | 420 | .p_memsz = @intCast(u32, self.program_headers.items[i].p_memsz), |
| | 421 | .p_align = @intCast(u32, self.program_headers.items[i].p_align), |
| | 422 | }; |
| | 423 | if (foreign_endian) { |
| | 424 | bswapAllFields(elf.Elf32_Phdr, phdr); |
| | 425 | } |
| | 426 | } |
| | 427 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); |
| | 428 | }, |
| | 429 | .p64 => { |
| | 430 | const buf = try allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len); |
| | 431 | defer allocator.free(buf); |
| | 432 | |
| | 433 | for (buf) |*phdr, i| { |
| | 434 | phdr.* = .{ |
| | 435 | .p_type = self.program_headers.items[i].p_type, |
| | 436 | .p_flags = self.program_headers.items[i].p_flags, |
| | 437 | .p_offset = self.program_headers.items[i].p_offset, |
| | 438 | .p_vaddr = self.program_headers.items[i].p_vaddr, |
| | 439 | .p_paddr = self.program_headers.items[i].p_paddr, |
| | 440 | .p_filesz = self.program_headers.items[i].p_filesz, |
| | 441 | .p_memsz = self.program_headers.items[i].p_memsz, |
| | 442 | .p_align = self.program_headers.items[i].p_align, |
| | 443 | }; |
| | 444 | if (foreign_endian) { |
| | 445 | bswapAllFields(elf.Elf64_Phdr, phdr); |
| | 446 | } |
| | 447 | } |
| | 448 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); |
| | 449 | }, |
| | 450 | } |
| | 451 | } |
| 450 | | 452 | |
| 451 | const shstrtab_sect = &self.sections.items[self.shstrtab_index.?]; | 453 | const shstrtab_sect = &self.sections.items[self.shstrtab_index.?]; |
| 452 | if (shstrtab_dirty or self.shstrtab.items.len != shstrtab_sect.sh_size) { | 454 | if (shstrtab_dirty or self.shstrtab.items.len != shstrtab_sect.sh_size) { |
| ... | @@ -590,7 +592,7 @@ const Update = struct { | ... | @@ -590,7 +592,7 @@ const Update = struct { |
| 590 | try self.file.pwriteAll(hdr_buf[0..index], 0); | 592 | try self.file.pwriteAll(hdr_buf[0..index], 0); |
| 591 | } | 593 | } |
| 592 | | 594 | |
| 593 | fn writeCodeAndSymbols(self: *Update) !void { | 595 | fn writeCodeAndSymbols(self: *Update, phdr_table_dirty: *bool) !void { |
| 594 | // index 0 is always a null symbol | 596 | // index 0 is always a null symbol |
| 595 | try self.symbols.resize(1); | 597 | try self.symbols.resize(1); |
| 596 | self.symbols.items[0] = .{ | 598 | self.symbols.items[0] = .{ |
| ... | @@ -638,6 +640,14 @@ const Update = struct { | ... | @@ -638,6 +640,14 @@ const Update = struct { |
| 638 | vaddr += code.items.len; | 640 | vaddr += code.items.len; |
| 639 | } | 641 | } |
| 640 | | 642 | |
| | 643 | { |
| | 644 | // Now that we know the code size, we need to update the program header for executable code |
| | 645 | phdr.p_memsz = vaddr - phdr.p_vaddr; |
| | 646 | phdr.p_filesz = phdr.p_memsz; |
| | 647 | |
| | 648 | phdr_table_dirty.* = true; |
| | 649 | } |
| | 650 | |
| 641 | return self.writeSymbols(); | 651 | return self.writeSymbols(); |
| 642 | } | 652 | } |
| 643 | | 653 | |