diff --git a/macho/dumper.cc b/macho/dumper.cc index 613f1767..edc6c10a 100644 --- a/macho/dumper.cc +++ b/macho/dumper.cc @@ -476,25 +476,25 @@ void dump_file(std::string path) { LinkEditDataCommand &cmd = *(LinkEditDataCommand *)&lc; CodeSignatureHeader &sig = *(CodeSignatureHeader *)(buf + cmd.dataoff); - std::cout << " magic: " << read32be((u8 *)&sig.magic) - << "\n length: " << read32be((u8 *)&sig.length) - << "\n count: " << read32be((u8 *)&sig.count) + std::cout << " magic: " << read32be(&sig.magic) + << "\n length: " << read32be(&sig.length) + << "\n count: " << read32be(&sig.count) << "\n"; - for (i64 i = 0; i < read32be((u8 *)&sig.count); i++) { - CodeSignatureBlobIndex &idx = *(CodeSignatureBlobIndex *)(&sig + i + 1); - std::cout << " idx type: " << read32be((u8 *)&idx.type) - << "\n idx offset: " << read32be((u8 *)&idx.offset) + for (i64 i = 0; i < read32be(&sig.count); i++) { + CodeSignatureBlobIndex &idx = ((CodeSignatureBlobIndex *)(&sig + 1))[i]; + std::cout << " idx type: " << read32be(&idx.type) + << "\n idx offset: " << read32be(&idx.offset) << "\n"; CodeSignatureDirectory &dir = - *(CodeSignatureDirectory *)((u8 *)&sig + read32be((u8 *)&idx.offset)); + *(CodeSignatureDirectory *)((u8 *)&sig + read32be(&idx.offset)); std::cout << std::hex - << " magic: 0x" << read32be((u8 *)&dir.magic) - << "\n version: 0x" << read32be((u8 *)&dir.version) - << "\n flags: 0x" << read32be((u8 *)&dir.flags) - << "\n hash_offset: 0x" << read32be((u8 *)&dir.hash_offset) - << "\n n_code_slots: 0x" << read32be((u8 *)&dir.n_code_slots) + << " magic: 0x" << read32be(&dir.magic) + << "\n version: 0x" << read32be(&dir.version) + << "\n flags: 0x" << read32be(&dir.flags) + << "\n hash_offset: 0x" << read32be(&dir.hash_offset) + << "\n n_code_slots: 0x" << read32be(&dir.n_code_slots) << "\n hash_size: 0x" << (u32)dir.hash_size << "\n hash_type: 0x" << (u32)dir.hash_type << "\n page_size: 0x" << (1 << dir.page_size) diff --git a/macho/main.cc b/macho/main.cc index 7d36a062..b305f69b 100644 --- a/macho/main.cc +++ b/macho/main.cc @@ -288,6 +288,7 @@ int main(int argc, char **argv) { for (std::unique_ptr &seg : ctx.segments) seg->copy_buf(ctx); + ctx.code_sig.write_signature(ctx); ctx.output_file->close(ctx); ctx.checkpoint(); diff --git a/macho/mold.h b/macho/mold.h index c4a48d65..e35c216a 100644 --- a/macho/mold.h +++ b/macho/mold.h @@ -14,6 +14,7 @@ namespace mold::macho { static constexpr i64 PAGE_SIZE = 0x4000; static constexpr i64 PAGE_ZERO_SIZE = 0x100000000; +static constexpr i64 SHA256_SIZE = 32; class Chunk; class OutputSection; @@ -458,6 +459,8 @@ public: void compute_size(Context &ctx) override; void write_signature(Context &ctx); + + static constexpr i64 BLOCK_SIZE = 4096; }; class StubsSection : public Chunk { diff --git a/macho/output-chunks.cc b/macho/output-chunks.cc index b63f5ac2..552c95e9 100644 --- a/macho/output-chunks.cc +++ b/macho/output-chunks.cc @@ -803,6 +803,16 @@ void OutputIndirectSymtabSection::copy_buf(Context &ctx) { } void CodeSignatureSection::compute_size(Context &ctx) { + i64 num_blocks = align_to(hdr.offset, BLOCK_SIZE) / BLOCK_SIZE; + hdr.size = sizeof(CodeSignatureHeader) + sizeof(CodeSignatureBlobIndex) + + num_blocks * SHA256_SIZE; +} + +void CodeSignatureSection::write_signature(Context &ctx) { + u8 *buf = ctx.buf + hdr.offset; + + CodeSignatureHeader &sighdr = *(CodeSignatureHeader *)buf; + write32be(&sighdr.magic, CSMAGIC_EMBEDDED_SIGNATURE); } void StubsSection::add(Context &ctx, Symbol *sym) { diff --git a/mold.h b/mold.h index 69c2f130..d8ef0ea2 100644 --- a/mold.h +++ b/mold.h @@ -178,45 +178,55 @@ inline void sort(T &vec, U less) { std::stable_sort(vec.begin(), vec.end(), less); } -inline u64 read64be(u8 *buf) { - return ((u64)buf[0] << 56) | ((u64)buf[1] << 48) | - ((u64)buf[2] << 40) | ((u64)buf[3] << 32) | - ((u64)buf[4] << 24) | ((u64)buf[5] << 16) | - ((u64)buf[6] << 8) | (u64)buf[7]; -} - -inline u64 read32be(u8 *buf) { +template +inline u64 read64be(T *buf) { u8 *p = (u8 *)buf; - return ((u64)buf[0] << 24) | ((u64)buf[1] << 16) | - ((u64)buf[2] << 8) | (u64)buf[3]; + return ((u64)p[0] << 56) | ((u64)p[1] << 48) | + ((u64)p[2] << 40) | ((u64)p[3] << 32) | + ((u64)p[4] << 24) | ((u64)p[5] << 16) | + ((u64)p[6] << 8) | (u64)p[7]; } -inline u64 read16be(u8 *buf) { +template +inline u64 read32be(T *buf) { u8 *p = (u8 *)buf; - return ((u64)buf[0] << 8) | (u64)buf[1]; + return ((u64)p[0] << 24) | ((u64)p[1] << 16) | + ((u64)p[2] << 8) | (u64)p[3]; } -inline void write64be(u8 *buf, u64 val) { - buf[0] = val >> 56; - buf[1] = val >> 48; - buf[2] = val >> 40; - buf[3] = val >> 32; - buf[4] = val >> 24; - buf[5] = val >> 16; - buf[6] = val >> 8; - buf[7] = val; +template +inline u64 read16be(T *buf) { + u8 *p = (u8 *)buf; + return ((u64)p[0] << 8) | (u64)p[1]; } -inline void write32be(u8 *buf, u64 val) { - buf[0] = val >> 24; - buf[1] = val >> 16; - buf[2] = val >> 8; - buf[3] = val; +template +inline void write64be(T *buf, u64 val) { + u8 *p = (u8 *)buf; + p[0] = val >> 56; + p[1] = val >> 48; + p[2] = val >> 40; + p[3] = val >> 32; + p[4] = val >> 24; + p[5] = val >> 16; + p[6] = val >> 8; + p[7] = val; } -inline void write16be(u8 *buf, u64 val) { - buf[0] = val >> 8; - buf[1] = val; +template +inline void write32be(T *buf, u32 val) { + u8 *p = (u8 *)buf; + p[0] = val >> 24; + p[1] = val >> 16; + p[2] = val >> 8; + p[3] = val; +} + +template +inline void write16be(T *buf, u32 val) { + u8 *p = (u8 *)buf; + p[0] = val >> 8; + p[1] = val; } inline i64 write_string(u8 *buf, std::string_view str) {