Implement SHA-1 and delete build id
This commit is contained in:
		
							parent
							
								
									fca4453d1e
								
							
						
					
					
						commit
						c8f0a62487
					
				
							
								
								
									
										162
									
								
								bootstrap/lib.h
									
									
									
									
									
								
							
							
						
						
									
										162
									
								
								bootstrap/lib.h
									
									
									
									
									
								
							| @ -3203,6 +3203,168 @@ fn MD5Result md5_end(MD5Context* context) | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| // https://github.com/jasinb/sha1.git
 | ||||
| STRUCT(Sha1Digest) | ||||
| { | ||||
|     u32 digest[5]; | ||||
| }; | ||||
| 
 | ||||
| // static uint32_t rotl32(uint32_t x, int b)
 | ||||
| // {
 | ||||
| //     return (x << b) | (x >> (32-b));
 | ||||
| // }
 | ||||
| //
 | ||||
| // switch endianness
 | ||||
| fn u32 sha1_get32(u8* p) | ||||
| { | ||||
|     return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; | ||||
| } | ||||
| 
 | ||||
| fn u32 sha1_f(int t, u32 b, u32 c, u32 d) | ||||
| { | ||||
|     assert(0 <= t && t < 80); | ||||
| 
 | ||||
|     if (t < 20) | ||||
|     { | ||||
|         return (b & c) | ((~b) & d); | ||||
|     } | ||||
|     else if (t < 40) | ||||
|     { | ||||
|         return b ^ c ^ d; | ||||
|     } | ||||
|     else if (t < 60) | ||||
|     { | ||||
|         return (b & c) | (b & d) | (c & d); | ||||
|     } | ||||
|     else | ||||
|     //if (t < 80)
 | ||||
|     { | ||||
|         return b ^ c ^ d; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| STRUCT(Sha1Context) | ||||
| { | ||||
|     u8 block[64]; | ||||
|     u32 h[5]; | ||||
|     u64 bytes; | ||||
|     u32 cur; | ||||
| }; | ||||
| 
 | ||||
| fn void sha1_reset(Sha1Context* ctx) | ||||
| { | ||||
|     ctx->h[0] = 0x67452301; | ||||
|     ctx->h[1] = 0xefcdab89; | ||||
|     ctx->h[2] = 0x98badcfe; | ||||
|     ctx->h[3] = 0x10325476; | ||||
|     ctx->h[4] = 0xc3d2e1f0; | ||||
|     ctx->bytes = 0; | ||||
|     ctx->cur = 0; | ||||
| } | ||||
| 
 | ||||
| fn void sha1_process_block(Sha1Context* ctx) | ||||
| { | ||||
|     global const u32 k[4] = | ||||
|     { | ||||
|         0x5A827999, | ||||
|         0x6ED9EBA1, | ||||
|         0x8F1BBCDC, | ||||
|         0xCA62C1D6 | ||||
|     }; | ||||
| 
 | ||||
|     u32 w[16]; | ||||
|     u32 a = ctx->h[0]; | ||||
|     u32 b = ctx->h[1]; | ||||
|     u32 c = ctx->h[2]; | ||||
|     u32 d = ctx->h[3]; | ||||
|     u32 e = ctx->h[4]; | ||||
|     u32 t; | ||||
| 
 | ||||
|     for (t = 0; t < 16; t++) | ||||
|         w[t] = sha1_get32((u8*)(&((uint32_t*)ctx->block)[t])); | ||||
| 
 | ||||
|     for (t = 0; t < 80; t++) | ||||
|     { | ||||
|         auto s = t & 0xf; | ||||
|         u32 temp; | ||||
|         if (t >= 16) | ||||
|             w[s] = rotate_left_u32(w[(s + 13) & 0xf] ^ w[(s + 8) & 0xf] ^ w[(s + 2) & 0xf] ^ w[s], 1); | ||||
| 
 | ||||
|          temp = rotate_left_u32(a, 5) + sha1_f(t, b,c,d) + e + w[s] + k[t/20]; | ||||
| 
 | ||||
|          e = d; d = c; c = rotate_left_u32(b, 30); b = a; a = temp; | ||||
|     } | ||||
| 
 | ||||
|     ctx->h[0] += a; | ||||
|     ctx->h[1] += b; | ||||
|     ctx->h[2] += c; | ||||
|     ctx->h[3] += d; | ||||
|     ctx->h[4] += e; | ||||
| } | ||||
| 
 | ||||
| fn void sha1_write(Sha1Context* ctx, String bytes) | ||||
| { | ||||
|     auto length = bytes.length; | ||||
|     ctx->bytes += length; | ||||
| 
 | ||||
|     const uint8_t* src = bytes.pointer; | ||||
|     while (length--) | ||||
|     { | ||||
|         // TODO: could optimize the first and last few bytes, and then copy
 | ||||
|         // 128 bit blocks with SIMD in between
 | ||||
|         ctx->block[ctx->cur++] = *src++; | ||||
|         if (ctx->cur == 64) | ||||
|         { | ||||
|             sha1_process_block(ctx); | ||||
|             ctx->cur = 0; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn Sha1Digest sha1_get_digest(Sha1Context* ctx) | ||||
| { | ||||
|     // append separator
 | ||||
|     ctx->block[ctx->cur++] = 0x80; | ||||
|     if (ctx->cur > 56) | ||||
|     { | ||||
|         // no space in block for the 64-bit message length, flush
 | ||||
|         memset(&ctx->block[ctx->cur], 0, 64 - ctx->cur); | ||||
|         sha1_process_block(ctx); | ||||
|         ctx->cur = 0; | ||||
|     } | ||||
| 
 | ||||
|     memset(&ctx->block[ctx->cur], 0, 56 - ctx->cur); | ||||
|     uint64_t bits = ctx->bytes * 8; | ||||
| 
 | ||||
|     // TODO a few instructions could be shaven
 | ||||
|     ctx->block[56] = (uint8_t)(bits >> 56 & 0xff); | ||||
|     ctx->block[57] = (uint8_t)(bits >> 48 & 0xff); | ||||
|     ctx->block[58] = (uint8_t)(bits >> 40 & 0xff); | ||||
|     ctx->block[59] = (uint8_t)(bits >> 32 & 0xff); | ||||
|     ctx->block[60] = (uint8_t)(bits >> 24 & 0xff); | ||||
|     ctx->block[61] = (uint8_t)(bits >> 16 & 0xff); | ||||
|     ctx->block[62] = (uint8_t)(bits >> 8  & 0xff); | ||||
|     ctx->block[63] = (uint8_t)(bits >> 0  & 0xff); | ||||
|     sha1_process_block(ctx); | ||||
| 
 | ||||
|     { | ||||
|         Sha1Digest ret; | ||||
|         int i; | ||||
|         for (i = 0; i < 5; i++) | ||||
|             ret.digest[i] = sha1_get32((u8*)&ctx->h[i]); | ||||
|         sha1_reset(ctx); | ||||
|         return ret; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn Sha1Digest sha1_compute(String bytes) | ||||
| { | ||||
|     Sha1Context ctx; | ||||
|     sha1_reset(&ctx); | ||||
|     sha1_write(&ctx, bytes); | ||||
|     return sha1_get_digest(&ctx); | ||||
| } | ||||
| 
 | ||||
| fn void entry_point(int argc, char* argv[], char* envp[]); | ||||
| 
 | ||||
| #if LINK_LIBC | ||||
|  | ||||
							
								
								
									
										128
									
								
								bootstrap/main.c
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								bootstrap/main.c
									
									
									
									
									
								
							| @ -8029,6 +8029,8 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr | ||||
|     u32 gnu_property_offset = 0; | ||||
|     u32 gnu_property_size = 0; | ||||
|     u32 gnu_property_alignment = 0; | ||||
|     auto gnu_string = strlit("GNU"); | ||||
|     auto gnu_string_size = gnu_string.length + 1; | ||||
|     { | ||||
|         // .note.gnu.property
 | ||||
|         // Section #2
 | ||||
| @ -8040,8 +8042,6 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr | ||||
|         gnu_property_offset = offset; | ||||
|         auto gnu_property_section_name = elf_get_section_name(builder, strlit(".note.gnu.property")); | ||||
| 
 | ||||
|         auto gnu_string = strlit("GNU"); | ||||
|         auto gnu_string_size = gnu_string.length + 1; | ||||
|         auto* ptr = vb_add_struct(&builder->file, ELFNoteHeader); | ||||
|         *ptr = (ELFNoteHeader) | ||||
|         { | ||||
| @ -8074,61 +8074,59 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     u32 gnu_build_id_offset = 0; | ||||
|     u32 gnu_build_id_alignment = 0; | ||||
|     { | ||||
|         // .note.gnu.build-id
 | ||||
|         // Section #3
 | ||||
|         auto* section_header = vb_add(&builder->section_headers, 1); | ||||
|         u64 alignment = 4; | ||||
|         gnu_build_id_alignment = alignment; | ||||
|         auto name = elf_get_section_name(builder, strlit(".note.gnu.build-id")); | ||||
|         vb_align(&builder->file, alignment); | ||||
|         auto offset = builder->file.length; | ||||
|         gnu_build_id_offset = offset; | ||||
| 
 | ||||
|         auto gnu_string = strlit("GNU"); | ||||
|         auto gnu_string_size = gnu_string.length + 1; | ||||
| 
 | ||||
|         u8 blob[] = { 0xF0, 0xDE, 0x30, 0xDB, 0x5A, 0x9F, 0xE2, 0x4E, 0x0A, 0xCF, 0x93, 0xA4, 0x4C, 0x11, 0x60, 0xB5, 0x0C, 0xD9, 0xAF, 0x50, }; | ||||
|         static_assert(sizeof(blob) == 20); | ||||
| 
 | ||||
|         *(vb_add_struct(&builder->file, ELFNoteHeader)) = (ELFNoteHeader) | ||||
|         { | ||||
|             .name_size = gnu_string_size, | ||||
|             .descriptor_size = sizeof(blob), | ||||
|             .type = NT_GNU_BUILD_ID, | ||||
|         }; | ||||
|         memcpy(vb_add(&builder->file, gnu_string_size), gnu_string.pointer, gnu_string_size); | ||||
|         memcpy(vb_add(&builder->file, sizeof(blob)), blob, sizeof(blob)); | ||||
| 
 | ||||
|         auto size = builder->file.length - offset; | ||||
| 
 | ||||
|         *section_header = (ELFSectionHeader) | ||||
|         { | ||||
|             .name_offset = name, | ||||
|             .type = ELF_SECTION_NOTE, | ||||
|             .flags = { | ||||
|                 .alloc = 1, | ||||
|             }, | ||||
|             .address = offset, | ||||
|             .offset = offset, | ||||
|             .size = size, | ||||
|             .link = 0, | ||||
|             .info = 0, | ||||
|             .alignment = alignment, | ||||
|             .entry_size = 0, | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     // u32 gnu_build_id_offset = 0;
 | ||||
|     // u32 gnu_build_id_alignment = 0;
 | ||||
|     // ELFNoteHeader* gnu_build_id_header = 0;
 | ||||
|     // u8* gnu_build_id_string = 0;
 | ||||
|     // u8* gnu_build_id_blob = 0;
 | ||||
|     // u32 gnu_build_id_blob_size = 20;
 | ||||
|     // {
 | ||||
|     //     // .note.gnu.build-id
 | ||||
|     //     // Section #3
 | ||||
|     //     auto* section_header = vb_add(&builder->section_headers, 1);
 | ||||
|     //     u64 alignment = 4;
 | ||||
|     //     gnu_build_id_alignment = alignment;
 | ||||
|     //     auto name = elf_get_section_name(builder, strlit(".note.gnu.build-id"));
 | ||||
|     //     vb_align(&builder->file, alignment);
 | ||||
|     //     auto offset = builder->file.length;
 | ||||
|     //     gnu_build_id_offset = offset;
 | ||||
|     //
 | ||||
|     //     gnu_build_id_header = vb_add_struct(&builder->file, ELFNoteHeader);
 | ||||
|     //     gnu_build_id_string = vb_add(&builder->file, gnu_string_size);
 | ||||
|     //     gnu_build_id_blob = vb_add(&builder->file, gnu_build_id_blob_size);
 | ||||
|     //
 | ||||
|     //     auto size = builder->file.length - offset;
 | ||||
|     //     memset(builder->file.pointer + offset, 0, size);
 | ||||
|     //
 | ||||
|     //     *section_header = (ELFSectionHeader)
 | ||||
|     //     {
 | ||||
|     //         .name_offset = name,
 | ||||
|     //         .type = ELF_SECTION_NOTE,
 | ||||
|     //         .flags = {
 | ||||
|     //             .alloc = 1,
 | ||||
|     //         },
 | ||||
|     //         .address = offset,
 | ||||
|     //         .offset = offset,
 | ||||
|     //         .size = size,
 | ||||
|     //         .link = 0,
 | ||||
|     //         .info = 0,
 | ||||
|     //         .alignment = alignment,
 | ||||
|     //         .entry_size = 0,
 | ||||
|     //     };
 | ||||
|     // }
 | ||||
|      | ||||
|     u32 gnu_build_id_abi_note_offset = 0; | ||||
|     u32 gnu_build_id_abi_alignment = 0; | ||||
|     { | ||||
|         // .note.ABI-tag
 | ||||
|         // Section #4
 | ||||
|         auto* section_header = vb_add(&builder->section_headers, 1); | ||||
|         u64 alignment = 4; | ||||
|         gnu_build_id_abi_alignment = alignment; | ||||
| 
 | ||||
|         vb_align(&builder->file, alignment); | ||||
|         auto offset = builder->file.length; | ||||
|         gnu_build_id_abi_note_offset = offset; | ||||
| 
 | ||||
|         auto name = elf_get_section_name(builder, strlit(".note.ABI-tag")); | ||||
| 
 | ||||
| @ -8168,7 +8166,7 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     auto gnu_build_id_abi_note_size = builder->file.length - gnu_build_id_offset; | ||||
|     auto gnu_build_id_abi_note_size = builder->file.length - gnu_build_id_abi_note_offset; | ||||
| 
 | ||||
|     u16 preliminar_section_count = builder->section_headers.length + 1; | ||||
|     auto dynamic_symbol_table_index = preliminar_section_count; | ||||
| @ -8491,7 +8489,6 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr | ||||
|     // Add read-only program segment
 | ||||
|     { | ||||
|         auto offset = builder->file.length; | ||||
|         assert(offset == 1496); | ||||
| 
 | ||||
|         *vb_add(&builder->program_headers, 1) = (ElfProgramHeader) | ||||
|         { | ||||
| @ -9240,12 +9237,12 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr | ||||
|         *vb_add(&builder->program_headers, 1) = (ElfProgramHeader) { | ||||
|             .type = PT_NOTE, | ||||
|             .flags = {.readable = 1}, | ||||
|             .offset = gnu_build_id_offset, | ||||
|             .virtual_address = gnu_build_id_offset, | ||||
|             .physical_address = gnu_build_id_offset, | ||||
|             .offset = gnu_build_id_abi_note_offset, | ||||
|             .virtual_address = gnu_build_id_abi_note_offset, | ||||
|             .physical_address = gnu_build_id_abi_note_offset, | ||||
|             .file_size = gnu_build_id_abi_note_size, | ||||
|             .memory_size = gnu_build_id_abi_note_size, | ||||
|             .alignment = gnu_build_id_alignment, | ||||
|             .alignment = gnu_build_id_abi_alignment, | ||||
|         }; | ||||
| 
 | ||||
|         *vb_add(&builder->program_headers, 1) = (ElfProgramHeader) { | ||||
| @ -9794,7 +9791,7 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr | ||||
|                 u8 directory_index; | ||||
|                 MD5Result hash; | ||||
|             }; | ||||
|             MD5Result md5_hash = {  { 0x05, 0xAB, 0x89, 0xF5, 0x48, 0x1B, 0xC9, 0xF2, 0xD0, 0x37, 0xE7, 0x88, 0x66, 0x41, 0xE9, 0x19 } }; | ||||
|             MD5Result md5_hash = { { 0x05, 0xAB, 0x89, 0xF5, 0x48, 0x1B, 0xC9, 0xF2, 0xD0, 0x37, 0xE7, 0x88, 0x66, 0x41, 0xE9, 0x19 } }; | ||||
| #if 0 | ||||
|             String dummy_file = file_read(thread->arena, strlit("/home/david/minimal/main.c")); | ||||
|             auto md5 = md5_init(); | ||||
| @ -10371,6 +10368,25 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr | ||||
| 
 | ||||
|     assert(relocation_index == expected_relocation_count); | ||||
| 
 | ||||
|     // // .note.gnu.build-id
 | ||||
|     // {
 | ||||
|     //     u8 blob[] = { 0xF0, 0xDE, 0x30, 0xDB, 0x5A, 0x9F, 0xE2, 0x4E, 0x0A, 0xCF, 0x93, 0xA4, 0x4C, 0x11, 0x60, 0xB5, 0x0C, 0xD9, 0xAF, 0x50, };
 | ||||
|     //
 | ||||
|     //     // *gnu_build_id_header = (ELFNoteHeader)
 | ||||
|     //     // {
 | ||||
|     //     //     .name_size = gnu_string_size,
 | ||||
|     //     //     .descriptor_size = sizeof(blob),
 | ||||
|     //     //     .type = NT_GNU_BUILD_ID,
 | ||||
|     //     // };
 | ||||
|     //     // memcpy(gnu_build_id_string, gnu_string.pointer, gnu_string_size);
 | ||||
|     //
 | ||||
|     //     auto f = file_read(thread->arena, strlit("/home/david/minimal/main"));
 | ||||
|     //     String exe = { builder->file.pointer, builder->file.length };
 | ||||
|     //     auto sha1 = sha1_compute(exe);
 | ||||
|     //     assert(sizeof(blob) == gnu_build_id_blob_size);
 | ||||
|     //     // memcpy(gnu_build_id_blob, blob, sizeof(blob));
 | ||||
|     // }
 | ||||
| 
 | ||||
|     // Check if the file matches
 | ||||
|      | ||||
|     // {
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 David Gonzalez Martin
						David Gonzalez Martin