| ... | @@ -174,7 +174,7 @@ const Update = struct { | ... | @@ -174,7 +174,7 @@ const Update = struct { |
| 174 | if (program_header.p_offset <= start) continue; | 174 | if (program_header.p_offset <= start) continue; |
| 175 | if (program_header.p_offset < min_pos) min_pos = program_header.p_offset; | 175 | if (program_header.p_offset < min_pos) min_pos = program_header.p_offset; |
| 176 | } | 176 | } |
| 177 | return min_pos; | 177 | return min_pos - start; |
| 178 | } | 178 | } |
| 179 | | 179 | |
| 180 | fn findFreeSpace(self: *Update, object_size: u64, min_alignment: u16) u64 { | 180 | fn findFreeSpace(self: *Update, object_size: u64, min_alignment: u16) u64 { |
| ... | @@ -233,7 +233,7 @@ const Update = struct { | ... | @@ -233,7 +233,7 @@ const Update = struct { |
| 233 | // There must always be a null section in index 0 | 233 | // There must always be a null section in index 0 |
| 234 | try self.sections.append(.{ | 234 | try self.sections.append(.{ |
| 235 | .sh_name = 0, | 235 | .sh_name = 0, |
| 236 | .sh_type = 0, | 236 | .sh_type = elf.SHT_NULL, |
| 237 | .sh_flags = 0, | 237 | .sh_flags = 0, |
| 238 | .sh_addr = 0, | 238 | .sh_addr = 0, |
| 239 | .sh_offset = 0, | 239 | .sh_offset = 0, |
| ... | @@ -247,6 +247,8 @@ const Update = struct { | ... | @@ -247,6 +247,8 @@ const Update = struct { |
| 247 | } | 247 | } |
| 248 | if (self.shstrtab_index == null) { | 248 | if (self.shstrtab_index == null) { |
| 249 | self.shstrtab_index = @intCast(u16, self.sections.items.len); | 249 | self.shstrtab_index = @intCast(u16, self.sections.items.len); |
| | 250 | assert(self.shstrtab.items.len == 0); |
| | 251 | try self.shstrtab.append(0); // need a 0 at position 0 |
| 250 | const off = self.findFreeSpace(self.shstrtab.items.len, 1); | 252 | const off = self.findFreeSpace(self.shstrtab.items.len, 1); |
| 251 | //std.debug.warn("found shstrtab free space 0x{x} to 0x{x}\n", .{ off, off + self.shstrtab.items.len }); | 253 | //std.debug.warn("found shstrtab free space 0x{x} to 0x{x}\n", .{ off, off + self.shstrtab.items.len }); |
| 252 | try self.sections.append(.{ | 254 | try self.sections.append(.{ |
| ... | @@ -299,7 +301,6 @@ const Update = struct { | ... | @@ -299,7 +301,6 @@ const Update = struct { |
| 299 | .sh_size = file_size, | 301 | .sh_size = file_size, |
| 300 | // The section header index of the associated string table. | 302 | // The section header index of the associated string table. |
| 301 | .sh_link = self.shstrtab_index.?, | 303 | .sh_link = self.shstrtab_index.?, |
| 302 | // One greater than the symbol table index of the last local symbol (binding STB_LOCAL). | | |
| 303 | .sh_info = @intCast(u32, self.module.exports.len), | 304 | .sh_info = @intCast(u32, self.module.exports.len), |
| 304 | .sh_addralign = min_align, | 305 | .sh_addralign = min_align, |
| 305 | .sh_entsize = each_size, | 306 | .sh_entsize = each_size, |
| ... | @@ -332,136 +333,105 @@ const Update = struct { | ... | @@ -332,136 +333,105 @@ const Update = struct { |
| 332 | phdr_table_dirty = true; | 333 | phdr_table_dirty = true; |
| 333 | } | 334 | } |
| 334 | const foreign_endian = self.module.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); | 335 | const foreign_endian = self.module.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); |
| 335 | if (shdr_table_dirty) { | 336 | |
| 336 | const allocated_size = self.allocatedSize(self.shdr_table_offset.?); | 337 | try self.writeCodeAndSymbols(phdr_table_dirty, shdr_table_dirty); |
| 337 | const needed_size = self.sections.items.len * phsize; | 338 | |
| | 339 | if (phdr_table_dirty) { |
| | 340 | const allocated_size = self.allocatedSize(self.phdr_table_offset.?); |
| | 341 | const needed_size = self.program_headers.items.len * phsize; |
| 338 | | 342 | |
| 339 | if (needed_size > allocated_size) { | 343 | if (needed_size > allocated_size) { |
| 340 | self.shdr_table_offset = null; // free the space | 344 | self.phdr_table_offset = null; // free the space |
| 341 | self.shdr_table_offset = self.findFreeSpace(needed_size, phalign); | 345 | self.phdr_table_offset = self.findFreeSpace(needed_size, phalign); |
| 342 | } | 346 | } |
| 343 | | 347 | |
| 344 | const allocator = self.sections.allocator; | 348 | const allocator = self.program_headers.allocator; |
| 345 | switch (ptr_width) { | 349 | switch (ptr_width) { |
| 346 | .p32 => { | 350 | .p32 => { |
| 347 | const buf = try allocator.alloc(elf.Elf32_Shdr, self.sections.items.len); | 351 | const buf = try allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len); |
| 348 | defer allocator.free(buf); | 352 | defer allocator.free(buf); |
| 349 | | 353 | |
| 350 | for (buf) |*shdr, i| { | 354 | for (buf) |*phdr, i| { |
| 351 | shdr.* = .{ | 355 | phdr.* = progHeaderTo32(self.program_headers.items[i]); |
| 352 | .sh_name = self.sections.items[i].sh_name, | | |
| 353 | .sh_type = self.sections.items[i].sh_type, | | |
| 354 | .sh_flags = @intCast(u32, self.sections.items[i].sh_flags), | | |
| 355 | .sh_addr = @intCast(u32, self.sections.items[i].sh_addr), | | |
| 356 | .sh_offset = @intCast(u32, self.sections.items[i].sh_offset), | | |
| 357 | .sh_size = @intCast(u32, self.sections.items[i].sh_size), | | |
| 358 | .sh_link = self.sections.items[i].sh_link, | | |
| 359 | .sh_info = self.sections.items[i].sh_info, | | |
| 360 | .sh_addralign = @intCast(u32, self.sections.items[i].sh_addralign), | | |
| 361 | .sh_entsize = @intCast(u32, self.sections.items[i].sh_entsize), | | |
| 362 | }; | | |
| 363 | if (foreign_endian) { | 356 | if (foreign_endian) { |
| 364 | bswapAllFields(elf.Elf32_Shdr, shdr); | 357 | bswapAllFields(elf.Elf32_Phdr, phdr); |
| 365 | } | 358 | } |
| 366 | } | 359 | } |
| 367 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); | 360 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); |
| 368 | }, | 361 | }, |
| 369 | .p64 => { | 362 | .p64 => { |
| 370 | const buf = try allocator.alloc(elf.Elf64_Shdr, self.sections.items.len); | 363 | const buf = try allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len); |
| 371 | defer allocator.free(buf); | 364 | defer allocator.free(buf); |
| 372 | | 365 | |
| 373 | for (buf) |*shdr, i| { | 366 | for (buf) |*phdr, i| { |
| 374 | shdr.* = .{ | 367 | phdr.* = self.program_headers.items[i]; |
| 375 | .sh_name = self.sections.items[i].sh_name, | | |
| 376 | .sh_type = self.sections.items[i].sh_type, | | |
| 377 | .sh_flags = self.sections.items[i].sh_flags, | | |
| 378 | .sh_addr = self.sections.items[i].sh_addr, | | |
| 379 | .sh_offset = self.sections.items[i].sh_offset, | | |
| 380 | .sh_size = self.sections.items[i].sh_size, | | |
| 381 | .sh_link = self.sections.items[i].sh_link, | | |
| 382 | .sh_info = self.sections.items[i].sh_info, | | |
| 383 | .sh_addralign = self.sections.items[i].sh_addralign, | | |
| 384 | .sh_entsize = self.sections.items[i].sh_entsize, | | |
| 385 | }; | | |
| 386 | if (foreign_endian) { | 368 | if (foreign_endian) { |
| 387 | bswapAllFields(elf.Elf64_Shdr, shdr); | 369 | bswapAllFields(elf.Elf64_Phdr, phdr); |
| 388 | } | 370 | } |
| 389 | } | 371 | } |
| 390 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); | 372 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); |
| 391 | }, | 373 | }, |
| 392 | } | 374 | } |
| 393 | } | 375 | } |
| 394 | | 376 | |
| 395 | try self.writeCodeAndSymbols(&phdr_table_dirty); | 377 | { |
| | 378 | const shstrtab_sect = &self.sections.items[self.shstrtab_index.?]; |
| | 379 | if (shstrtab_dirty or self.shstrtab.items.len != shstrtab_sect.sh_size) { |
| | 380 | const allocated_size = self.allocatedSize(shstrtab_sect.sh_offset); |
| | 381 | const needed_size = self.shstrtab.items.len; |
| | 382 | |
| | 383 | if (needed_size > allocated_size) { |
| | 384 | shstrtab_sect.sh_size = 0; // free the space |
| | 385 | shstrtab_sect.sh_offset = self.findFreeSpace(needed_size, 1); |
| | 386 | } |
| | 387 | shstrtab_sect.sh_size = needed_size; |
| | 388 | //std.debug.warn("shstrtab start=0x{x} end=0x{x}\n", .{ shstrtab_sect.sh_offset, shstrtab_sect.sh_offset + needed_size }); |
| 396 | | 389 | |
| 397 | if (phdr_table_dirty) { | 390 | try self.file.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset); |
| 398 | const allocated_size = self.allocatedSize(self.phdr_table_offset.?); | 391 | if (!shdr_table_dirty) { |
| 399 | const needed_size = self.program_headers.items.len * phsize; | 392 | // Then it won't get written with the others and we need to do it. |
| | 393 | try self.writeSectHeader(self.shstrtab_index.?); |
| | 394 | } |
| | 395 | } |
| | 396 | } |
| | 397 | if (shdr_table_dirty) { |
| | 398 | const allocated_size = self.allocatedSize(self.shdr_table_offset.?); |
| | 399 | const needed_size = self.sections.items.len * phsize; |
| 400 | | 400 | |
| 401 | if (needed_size > allocated_size) { | 401 | if (needed_size > allocated_size) { |
| 402 | self.phdr_table_offset = null; // free the space | 402 | self.shdr_table_offset = null; // free the space |
| 403 | self.phdr_table_offset = self.findFreeSpace(needed_size, phalign); | 403 | self.shdr_table_offset = self.findFreeSpace(needed_size, phalign); |
| 404 | } | 404 | } |
| 405 | | 405 | |
| 406 | const allocator = self.program_headers.allocator; | 406 | const allocator = self.sections.allocator; |
| 407 | switch (ptr_width) { | 407 | switch (ptr_width) { |
| 408 | .p32 => { | 408 | .p32 => { |
| 409 | const buf = try allocator.alloc(elf.Elf32_Phdr, self.program_headers.items.len); | 409 | const buf = try allocator.alloc(elf.Elf32_Shdr, self.sections.items.len); |
| 410 | defer allocator.free(buf); | 410 | defer allocator.free(buf); |
| 411 | | 411 | |
| 412 | for (buf) |*phdr, i| { | 412 | for (buf) |*shdr, i| { |
| 413 | phdr.* = .{ | 413 | shdr.* = sectHeaderTo32(self.sections.items[i]); |
| 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) { | 414 | if (foreign_endian) { |
| 424 | bswapAllFields(elf.Elf32_Phdr, phdr); | 415 | bswapAllFields(elf.Elf32_Shdr, shdr); |
| 425 | } | 416 | } |
| 426 | } | 417 | } |
| 427 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); | 418 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 428 | }, | 419 | }, |
| 429 | .p64 => { | 420 | .p64 => { |
| 430 | const buf = try allocator.alloc(elf.Elf64_Phdr, self.program_headers.items.len); | 421 | const buf = try allocator.alloc(elf.Elf64_Shdr, self.sections.items.len); |
| 431 | defer allocator.free(buf); | 422 | defer allocator.free(buf); |
| 432 | | 423 | |
| 433 | for (buf) |*phdr, i| { | 424 | for (buf) |*shdr, i| { |
| 434 | phdr.* = .{ | 425 | shdr.* = self.sections.items[i]; |
| 435 | .p_type = self.program_headers.items[i].p_type, | 426 | //std.debug.warn("writing section {}\n", .{shdr.*}); |
| 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) { | 427 | if (foreign_endian) { |
| 445 | bswapAllFields(elf.Elf64_Phdr, phdr); | 428 | bswapAllFields(elf.Elf64_Shdr, shdr); |
| 446 | } | 429 | } |
| 447 | } | 430 | } |
| 448 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); | 431 | try self.file.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 449 | }, | 432 | }, |
| 450 | } | 433 | } |
| 451 | } | 434 | } |
| 452 | | | |
| 453 | const shstrtab_sect = &self.sections.items[self.shstrtab_index.?]; | | |
| 454 | if (shstrtab_dirty or self.shstrtab.items.len != shstrtab_sect.sh_size) { | | |
| 455 | const allocated_size = self.allocatedSize(shstrtab_sect.sh_offset); | | |
| 456 | const needed_size = self.shstrtab.items.len; | | |
| 457 | | | |
| 458 | if (needed_size > allocated_size) { | | |
| 459 | shstrtab_sect.sh_size = 0; // free the space | | |
| 460 | shstrtab_sect.sh_offset = self.findFreeSpace(needed_size, 1); | | |
| 461 | shstrtab_sect.sh_size = needed_size; | | |
| 462 | } | | |
| 463 | try self.file.pwriteAll(self.shstrtab.items, shstrtab_sect.sh_offset); | | |
| 464 | } | | |
| 465 | if (self.entry_addr == null) { | 435 | if (self.entry_addr == null) { |
| 466 | const msg = try std.fmt.allocPrint(self.errors.allocator, "no entry point found", .{}); | 436 | const msg = try std.fmt.allocPrint(self.errors.allocator, "no entry point found", .{}); |
| 467 | errdefer self.errors.allocator.free(msg); | 437 | errdefer self.errors.allocator.free(msg); |
| ... | @@ -592,7 +562,7 @@ const Update = struct { | ... | @@ -592,7 +562,7 @@ const Update = struct { |
| 592 | try self.file.pwriteAll(hdr_buf[0..index], 0); | 562 | try self.file.pwriteAll(hdr_buf[0..index], 0); |
| 593 | } | 563 | } |
| 594 | | 564 | |
| 595 | fn writeCodeAndSymbols(self: *Update, phdr_table_dirty: *bool) !void { | 565 | fn writeCodeAndSymbols(self: *Update, phdr_table_dirty: bool, shdr_table_dirty: bool) !void { |
| 596 | // index 0 is always a null symbol | 566 | // index 0 is always a null symbol |
| 597 | try self.symbols.resize(1); | 567 | try self.symbols.resize(1); |
| 598 | self.symbols.items[0] = .{ | 568 | self.symbols.items[0] = .{ |
| ... | @@ -606,6 +576,7 @@ const Update = struct { | ... | @@ -606,6 +576,7 @@ const Update = struct { |
| 606 | | 576 | |
| 607 | const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; | 577 | const phdr = &self.program_headers.items[self.phdr_load_re_index.?]; |
| 608 | var vaddr: u64 = phdr.p_vaddr; | 578 | var vaddr: u64 = phdr.p_vaddr; |
| | 579 | var file_off: u64 = phdr.p_offset; |
| 609 | | 580 | |
| 610 | var code = std.ArrayList(u8).init(self.sections.allocator); | 581 | var code = std.ArrayList(u8).init(self.sections.allocator); |
| 611 | defer code.deinit(); | 582 | defer code.deinit(); |
| ... | @@ -625,6 +596,7 @@ const Update = struct { | ... | @@ -625,6 +596,7 @@ const Update = struct { |
| 625 | } | 596 | } |
| 626 | continue; | 597 | continue; |
| 627 | } | 598 | } |
| | 599 | try self.file.pwriteAll(code.items, file_off); |
| 628 | | 600 | |
| 629 | if (mem.eql(u8, exp.name, "_start")) { | 601 | if (mem.eql(u8, exp.name, "_start")) { |
| 630 | self.entry_addr = vaddr; | 602 | self.entry_addr = vaddr; |
| ... | @@ -645,12 +617,67 @@ const Update = struct { | ... | @@ -645,12 +617,67 @@ const Update = struct { |
| 645 | phdr.p_memsz = vaddr - phdr.p_vaddr; | 617 | phdr.p_memsz = vaddr - phdr.p_vaddr; |
| 646 | phdr.p_filesz = phdr.p_memsz; | 618 | phdr.p_filesz = phdr.p_memsz; |
| 647 | | 619 | |
| 648 | phdr_table_dirty.* = true; | 620 | const shdr = &self.sections.items[self.text_section_index.?]; |
| | 621 | shdr.sh_size = phdr.p_filesz; |
| | 622 | |
| | 623 | if (!phdr_table_dirty) { |
| | 624 | // Then it won't get written with the others and we need to do it. |
| | 625 | try self.writeProgHeader(self.phdr_load_re_index.?); |
| | 626 | } |
| | 627 | if (!shdr_table_dirty) { |
| | 628 | // Then it won't get written with the others and we need to do it. |
| | 629 | try self.writeSectHeader(self.text_section_index.?); |
| | 630 | } |
| 649 | } | 631 | } |
| 650 | | 632 | |
| 651 | return self.writeSymbols(); | 633 | return self.writeSymbols(); |
| 652 | } | 634 | } |
| 653 | | 635 | |
| | 636 | fn writeProgHeader(self: *Update, index: usize) !void { |
| | 637 | const foreign_endian = self.module.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); |
| | 638 | const offset = self.program_headers.items[index].p_offset; |
| | 639 | switch (self.module.target.cpu.arch.ptrBitWidth()) { |
| | 640 | 32 => { |
| | 641 | var phdr = [1]elf.Elf32_Phdr{progHeaderTo32(self.program_headers.items[index])}; |
| | 642 | if (foreign_endian) { |
| | 643 | bswapAllFields(elf.Elf32_Phdr, &phdr[0]); |
| | 644 | } |
| | 645 | return self.file.pwriteAll(mem.sliceAsBytes(&phdr), offset); |
| | 646 | }, |
| | 647 | 64 => { |
| | 648 | var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]}; |
| | 649 | if (foreign_endian) { |
| | 650 | bswapAllFields(elf.Elf64_Phdr, &phdr[0]); |
| | 651 | } |
| | 652 | return self.file.pwriteAll(mem.sliceAsBytes(&phdr), offset); |
| | 653 | }, |
| | 654 | else => return error.UnsupportedArchitecture, |
| | 655 | } |
| | 656 | } |
| | 657 | |
| | 658 | fn writeSectHeader(self: *Update, index: usize) !void { |
| | 659 | const foreign_endian = self.module.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); |
| | 660 | const offset = self.sections.items[index].sh_offset; |
| | 661 | switch (self.module.target.cpu.arch.ptrBitWidth()) { |
| | 662 | 32 => { |
| | 663 | var shdr: [1]elf.Elf32_Shdr = undefined; |
| | 664 | shdr[0] = sectHeaderTo32(self.sections.items[index]); |
| | 665 | if (foreign_endian) { |
| | 666 | bswapAllFields(elf.Elf32_Shdr, &shdr[0]); |
| | 667 | } |
| | 668 | return self.file.pwriteAll(mem.sliceAsBytes(&shdr), offset); |
| | 669 | }, |
| | 670 | 64 => { |
| | 671 | var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]}; |
| | 672 | if (foreign_endian) { |
| | 673 | bswapAllFields(elf.Elf64_Shdr, &shdr[0]); |
| | 674 | } |
| | 675 | return self.file.pwriteAll(mem.sliceAsBytes(&shdr), offset); |
| | 676 | }, |
| | 677 | else => return error.UnsupportedArchitecture, |
| | 678 | } |
| | 679 | } |
| | 680 | |
| 654 | fn writeSymbols(self: *Update) !void { | 681 | fn writeSymbols(self: *Update) !void { |
| 655 | const ptr_width: enum { p32, p64 } = switch (self.module.target.cpu.arch.ptrBitWidth()) { | 682 | const ptr_width: enum { p32, p64 } = switch (self.module.target.cpu.arch.ptrBitWidth()) { |
| 656 | 32 => .p32, | 683 | 32 => .p32, |
| ... | @@ -667,8 +694,11 @@ const Update = struct { | ... | @@ -667,8 +694,11 @@ const Update = struct { |
| 667 | if (needed_size > allocated_size) { | 694 | if (needed_size > allocated_size) { |
| 668 | syms_sect.sh_size = 0; // free the space | 695 | syms_sect.sh_size = 0; // free the space |
| 669 | syms_sect.sh_offset = self.findFreeSpace(needed_size, sym_align); | 696 | syms_sect.sh_offset = self.findFreeSpace(needed_size, sym_align); |
| 670 | syms_sect.sh_size = needed_size; | 697 | //std.debug.warn("moved symtab to 0x{x} to 0x{x}\n", .{ syms_sect.sh_offset, syms_sect.sh_offset + needed_size }); |
| 671 | } | 698 | } |
| | 699 | //std.debug.warn("symtab start=0x{x} end=0x{x}\n", .{ syms_sect.sh_offset, syms_sect.sh_offset + needed_size }); |
| | 700 | syms_sect.sh_size = needed_size; |
| | 701 | syms_sect.sh_info = @intCast(u32, self.symbols.items.len); |
| 672 | const allocator = self.symbols.allocator; | 702 | const allocator = self.symbols.allocator; |
| 673 | const foreign_endian = self.module.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); | 703 | const foreign_endian = self.module.target.cpu.arch.endian() != std.Target.current.cpu.arch.endian(); |
| 674 | switch (ptr_width) { | 704 | switch (ptr_width) { |
| ... | @@ -760,3 +790,31 @@ fn satMul(a: var, b: var) @TypeOf(a, b) { | ... | @@ -760,3 +790,31 @@ fn satMul(a: var, b: var) @TypeOf(a, b) { |
| 760 | fn bswapAllFields(comptime S: type, ptr: *S) void { | 790 | fn bswapAllFields(comptime S: type, ptr: *S) void { |
| 761 | @panic("TODO implement bswapAllFields"); | 791 | @panic("TODO implement bswapAllFields"); |
| 762 | } | 792 | } |
| | 793 | |
| | 794 | fn progHeaderTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr { |
| | 795 | return .{ |
| | 796 | .p_type = phdr.p_type, |
| | 797 | .p_flags = phdr.p_flags, |
| | 798 | .p_offset = @intCast(u32, phdr.p_offset), |
| | 799 | .p_vaddr = @intCast(u32, phdr.p_vaddr), |
| | 800 | .p_paddr = @intCast(u32, phdr.p_paddr), |
| | 801 | .p_filesz = @intCast(u32, phdr.p_filesz), |
| | 802 | .p_memsz = @intCast(u32, phdr.p_memsz), |
| | 803 | .p_align = @intCast(u32, phdr.p_align), |
| | 804 | }; |
| | 805 | } |
| | 806 | |
| | 807 | fn sectHeaderTo32(shdr: elf.Elf64_Shdr) elf.Elf32_Shdr { |
| | 808 | return .{ |
| | 809 | .sh_name = shdr.sh_name, |
| | 810 | .sh_type = shdr.sh_type, |
| | 811 | .sh_flags = @intCast(u32, shdr.sh_flags), |
| | 812 | .sh_addr = @intCast(u32, shdr.sh_addr), |
| | 813 | .sh_offset = @intCast(u32, shdr.sh_offset), |
| | 814 | .sh_size = @intCast(u32, shdr.sh_size), |
| | 815 | .sh_link = shdr.sh_link, |
| | 816 | .sh_info = shdr.sh_info, |
| | 817 | .sh_addralign = @intCast(u32, shdr.sh_addralign), |
| | 818 | .sh_entsize = @intCast(u32, shdr.sh_entsize), |
| | 819 | }; |
| | 820 | } |