18c2ecf20Sopenharmony_ci#include <netinet/in.h> 28c2ecf20Sopenharmony_ci#ifdef __sun__ 38c2ecf20Sopenharmony_ci#include <inttypes.h> 48c2ecf20Sopenharmony_ci#else 58c2ecf20Sopenharmony_ci#include <stdint.h> 68c2ecf20Sopenharmony_ci#endif 78c2ecf20Sopenharmony_ci#include <ctype.h> 88c2ecf20Sopenharmony_ci#include <errno.h> 98c2ecf20Sopenharmony_ci#include <string.h> 108c2ecf20Sopenharmony_ci#include <limits.h> 118c2ecf20Sopenharmony_ci#include "modpost.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * Stolen form Cryptographic API. 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * MD4 Message Digest Algorithm (RFC1320). 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * Implementation derived from Andrew Tridgell and Steve French's 198c2ecf20Sopenharmony_ci * CIFS MD4 implementation, and the cryptoapi implementation 208c2ecf20Sopenharmony_ci * originally based on the public domain implementation written 218c2ecf20Sopenharmony_ci * by Colin Plumb in 1993. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * Copyright (c) Andrew Tridgell 1997-1998. 248c2ecf20Sopenharmony_ci * Modified by Steve French (sfrench@us.ibm.com) 2002 258c2ecf20Sopenharmony_ci * Copyright (c) Cryptoapi developers. 268c2ecf20Sopenharmony_ci * Copyright (c) 2002 David S. Miller (davem@redhat.com) 278c2ecf20Sopenharmony_ci * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 288c2ecf20Sopenharmony_ci * 298c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 308c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License as published by 318c2ecf20Sopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 328c2ecf20Sopenharmony_ci * (at your option) any later version. 338c2ecf20Sopenharmony_ci * 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_ci#define MD4_DIGEST_SIZE 16 368c2ecf20Sopenharmony_ci#define MD4_HMAC_BLOCK_SIZE 64 378c2ecf20Sopenharmony_ci#define MD4_BLOCK_WORDS 16 388c2ecf20Sopenharmony_ci#define MD4_HASH_WORDS 4 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistruct md4_ctx { 418c2ecf20Sopenharmony_ci uint32_t hash[MD4_HASH_WORDS]; 428c2ecf20Sopenharmony_ci uint32_t block[MD4_BLOCK_WORDS]; 438c2ecf20Sopenharmony_ci uint64_t byte_count; 448c2ecf20Sopenharmony_ci}; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic inline uint32_t lshift(uint32_t x, unsigned int s) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci x &= 0xFFFFFFFF; 498c2ecf20Sopenharmony_ci return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistatic inline uint32_t F(uint32_t x, uint32_t y, uint32_t z) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci return (x & y) | ((~x) & z); 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic inline uint32_t G(uint32_t x, uint32_t y, uint32_t z) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci return (x & y) | (x & z) | (y & z); 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistatic inline uint32_t H(uint32_t x, uint32_t y, uint32_t z) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci return x ^ y ^ z; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s)) 688c2ecf20Sopenharmony_ci#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (uint32_t)0x5A827999,s)) 698c2ecf20Sopenharmony_ci#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (uint32_t)0x6ED9EBA1,s)) 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* XXX: this stuff can be optimized */ 728c2ecf20Sopenharmony_cistatic inline void le32_to_cpu_array(uint32_t *buf, unsigned int words) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci while (words--) { 758c2ecf20Sopenharmony_ci *buf = ntohl(*buf); 768c2ecf20Sopenharmony_ci buf++; 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci} 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistatic inline void cpu_to_le32_array(uint32_t *buf, unsigned int words) 818c2ecf20Sopenharmony_ci{ 828c2ecf20Sopenharmony_ci while (words--) { 838c2ecf20Sopenharmony_ci *buf = htonl(*buf); 848c2ecf20Sopenharmony_ci buf++; 858c2ecf20Sopenharmony_ci } 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic void md4_transform(uint32_t *hash, uint32_t const *in) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci uint32_t a, b, c, d; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci a = hash[0]; 938c2ecf20Sopenharmony_ci b = hash[1]; 948c2ecf20Sopenharmony_ci c = hash[2]; 958c2ecf20Sopenharmony_ci d = hash[3]; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci ROUND1(a, b, c, d, in[0], 3); 988c2ecf20Sopenharmony_ci ROUND1(d, a, b, c, in[1], 7); 998c2ecf20Sopenharmony_ci ROUND1(c, d, a, b, in[2], 11); 1008c2ecf20Sopenharmony_ci ROUND1(b, c, d, a, in[3], 19); 1018c2ecf20Sopenharmony_ci ROUND1(a, b, c, d, in[4], 3); 1028c2ecf20Sopenharmony_ci ROUND1(d, a, b, c, in[5], 7); 1038c2ecf20Sopenharmony_ci ROUND1(c, d, a, b, in[6], 11); 1048c2ecf20Sopenharmony_ci ROUND1(b, c, d, a, in[7], 19); 1058c2ecf20Sopenharmony_ci ROUND1(a, b, c, d, in[8], 3); 1068c2ecf20Sopenharmony_ci ROUND1(d, a, b, c, in[9], 7); 1078c2ecf20Sopenharmony_ci ROUND1(c, d, a, b, in[10], 11); 1088c2ecf20Sopenharmony_ci ROUND1(b, c, d, a, in[11], 19); 1098c2ecf20Sopenharmony_ci ROUND1(a, b, c, d, in[12], 3); 1108c2ecf20Sopenharmony_ci ROUND1(d, a, b, c, in[13], 7); 1118c2ecf20Sopenharmony_ci ROUND1(c, d, a, b, in[14], 11); 1128c2ecf20Sopenharmony_ci ROUND1(b, c, d, a, in[15], 19); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci ROUND2(a, b, c, d,in[ 0], 3); 1158c2ecf20Sopenharmony_ci ROUND2(d, a, b, c, in[4], 5); 1168c2ecf20Sopenharmony_ci ROUND2(c, d, a, b, in[8], 9); 1178c2ecf20Sopenharmony_ci ROUND2(b, c, d, a, in[12], 13); 1188c2ecf20Sopenharmony_ci ROUND2(a, b, c, d, in[1], 3); 1198c2ecf20Sopenharmony_ci ROUND2(d, a, b, c, in[5], 5); 1208c2ecf20Sopenharmony_ci ROUND2(c, d, a, b, in[9], 9); 1218c2ecf20Sopenharmony_ci ROUND2(b, c, d, a, in[13], 13); 1228c2ecf20Sopenharmony_ci ROUND2(a, b, c, d, in[2], 3); 1238c2ecf20Sopenharmony_ci ROUND2(d, a, b, c, in[6], 5); 1248c2ecf20Sopenharmony_ci ROUND2(c, d, a, b, in[10], 9); 1258c2ecf20Sopenharmony_ci ROUND2(b, c, d, a, in[14], 13); 1268c2ecf20Sopenharmony_ci ROUND2(a, b, c, d, in[3], 3); 1278c2ecf20Sopenharmony_ci ROUND2(d, a, b, c, in[7], 5); 1288c2ecf20Sopenharmony_ci ROUND2(c, d, a, b, in[11], 9); 1298c2ecf20Sopenharmony_ci ROUND2(b, c, d, a, in[15], 13); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci ROUND3(a, b, c, d,in[ 0], 3); 1328c2ecf20Sopenharmony_ci ROUND3(d, a, b, c, in[8], 9); 1338c2ecf20Sopenharmony_ci ROUND3(c, d, a, b, in[4], 11); 1348c2ecf20Sopenharmony_ci ROUND3(b, c, d, a, in[12], 15); 1358c2ecf20Sopenharmony_ci ROUND3(a, b, c, d, in[2], 3); 1368c2ecf20Sopenharmony_ci ROUND3(d, a, b, c, in[10], 9); 1378c2ecf20Sopenharmony_ci ROUND3(c, d, a, b, in[6], 11); 1388c2ecf20Sopenharmony_ci ROUND3(b, c, d, a, in[14], 15); 1398c2ecf20Sopenharmony_ci ROUND3(a, b, c, d, in[1], 3); 1408c2ecf20Sopenharmony_ci ROUND3(d, a, b, c, in[9], 9); 1418c2ecf20Sopenharmony_ci ROUND3(c, d, a, b, in[5], 11); 1428c2ecf20Sopenharmony_ci ROUND3(b, c, d, a, in[13], 15); 1438c2ecf20Sopenharmony_ci ROUND3(a, b, c, d, in[3], 3); 1448c2ecf20Sopenharmony_ci ROUND3(d, a, b, c, in[11], 9); 1458c2ecf20Sopenharmony_ci ROUND3(c, d, a, b, in[7], 11); 1468c2ecf20Sopenharmony_ci ROUND3(b, c, d, a, in[15], 15); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci hash[0] += a; 1498c2ecf20Sopenharmony_ci hash[1] += b; 1508c2ecf20Sopenharmony_ci hash[2] += c; 1518c2ecf20Sopenharmony_ci hash[3] += d; 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic inline void md4_transform_helper(struct md4_ctx *ctx) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(uint32_t)); 1578c2ecf20Sopenharmony_ci md4_transform(ctx->hash, ctx->block); 1588c2ecf20Sopenharmony_ci} 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_cistatic void md4_init(struct md4_ctx *mctx) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci mctx->hash[0] = 0x67452301; 1638c2ecf20Sopenharmony_ci mctx->hash[1] = 0xefcdab89; 1648c2ecf20Sopenharmony_ci mctx->hash[2] = 0x98badcfe; 1658c2ecf20Sopenharmony_ci mctx->hash[3] = 0x10325476; 1668c2ecf20Sopenharmony_ci mctx->byte_count = 0; 1678c2ecf20Sopenharmony_ci} 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic void md4_update(struct md4_ctx *mctx, 1708c2ecf20Sopenharmony_ci const unsigned char *data, unsigned int len) 1718c2ecf20Sopenharmony_ci{ 1728c2ecf20Sopenharmony_ci const uint32_t avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci mctx->byte_count += len; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci if (avail > len) { 1778c2ecf20Sopenharmony_ci memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), 1788c2ecf20Sopenharmony_ci data, len); 1798c2ecf20Sopenharmony_ci return; 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), 1838c2ecf20Sopenharmony_ci data, avail); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci md4_transform_helper(mctx); 1868c2ecf20Sopenharmony_ci data += avail; 1878c2ecf20Sopenharmony_ci len -= avail; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci while (len >= sizeof(mctx->block)) { 1908c2ecf20Sopenharmony_ci memcpy(mctx->block, data, sizeof(mctx->block)); 1918c2ecf20Sopenharmony_ci md4_transform_helper(mctx); 1928c2ecf20Sopenharmony_ci data += sizeof(mctx->block); 1938c2ecf20Sopenharmony_ci len -= sizeof(mctx->block); 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci memcpy(mctx->block, data, len); 1978c2ecf20Sopenharmony_ci} 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cistatic void md4_final_ascii(struct md4_ctx *mctx, char *out, unsigned int len) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci const unsigned int offset = mctx->byte_count & 0x3f; 2028c2ecf20Sopenharmony_ci char *p = (char *)mctx->block + offset; 2038c2ecf20Sopenharmony_ci int padding = 56 - (offset + 1); 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci *p++ = 0x80; 2068c2ecf20Sopenharmony_ci if (padding < 0) { 2078c2ecf20Sopenharmony_ci memset(p, 0x00, padding + sizeof (uint64_t)); 2088c2ecf20Sopenharmony_ci md4_transform_helper(mctx); 2098c2ecf20Sopenharmony_ci p = (char *)mctx->block; 2108c2ecf20Sopenharmony_ci padding = 56; 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci memset(p, 0, padding); 2148c2ecf20Sopenharmony_ci mctx->block[14] = mctx->byte_count << 3; 2158c2ecf20Sopenharmony_ci mctx->block[15] = mctx->byte_count >> 29; 2168c2ecf20Sopenharmony_ci le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - 2178c2ecf20Sopenharmony_ci sizeof(uint64_t)) / sizeof(uint32_t)); 2188c2ecf20Sopenharmony_ci md4_transform(mctx->hash, mctx->block); 2198c2ecf20Sopenharmony_ci cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(uint32_t)); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci snprintf(out, len, "%08X%08X%08X%08X", 2228c2ecf20Sopenharmony_ci mctx->hash[0], mctx->hash[1], mctx->hash[2], mctx->hash[3]); 2238c2ecf20Sopenharmony_ci} 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic inline void add_char(unsigned char c, struct md4_ctx *md) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci md4_update(md, &c, 1); 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic int parse_string(const char *file, unsigned long len, 2318c2ecf20Sopenharmony_ci struct md4_ctx *md) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci unsigned long i; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci add_char(file[0], md); 2368c2ecf20Sopenharmony_ci for (i = 1; i < len; i++) { 2378c2ecf20Sopenharmony_ci add_char(file[i], md); 2388c2ecf20Sopenharmony_ci if (file[i] == '"' && file[i-1] != '\\') 2398c2ecf20Sopenharmony_ci break; 2408c2ecf20Sopenharmony_ci } 2418c2ecf20Sopenharmony_ci return i; 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cistatic int parse_comment(const char *file, unsigned long len) 2458c2ecf20Sopenharmony_ci{ 2468c2ecf20Sopenharmony_ci unsigned long i; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci for (i = 2; i < len; i++) { 2498c2ecf20Sopenharmony_ci if (file[i-1] == '*' && file[i] == '/') 2508c2ecf20Sopenharmony_ci break; 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci return i; 2538c2ecf20Sopenharmony_ci} 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci/* FIXME: Handle .s files differently (eg. # starts comments) --RR */ 2568c2ecf20Sopenharmony_cistatic int parse_file(const char *fname, struct md4_ctx *md) 2578c2ecf20Sopenharmony_ci{ 2588c2ecf20Sopenharmony_ci char *file; 2598c2ecf20Sopenharmony_ci unsigned long i, len; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci file = read_text_file(fname); 2628c2ecf20Sopenharmony_ci len = strlen(file); 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) { 2658c2ecf20Sopenharmony_ci /* Collapse and ignore \ and CR. */ 2668c2ecf20Sopenharmony_ci if (file[i] == '\\' && (i+1 < len) && file[i+1] == '\n') { 2678c2ecf20Sopenharmony_ci i++; 2688c2ecf20Sopenharmony_ci continue; 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci /* Ignore whitespace */ 2728c2ecf20Sopenharmony_ci if (isspace(file[i])) 2738c2ecf20Sopenharmony_ci continue; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci /* Handle strings as whole units */ 2768c2ecf20Sopenharmony_ci if (file[i] == '"') { 2778c2ecf20Sopenharmony_ci i += parse_string(file+i, len - i, md); 2788c2ecf20Sopenharmony_ci continue; 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci /* Comments: ignore */ 2828c2ecf20Sopenharmony_ci if (file[i] == '/' && file[i+1] == '*') { 2838c2ecf20Sopenharmony_ci i += parse_comment(file+i, len - i); 2848c2ecf20Sopenharmony_ci continue; 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci add_char(file[i], md); 2888c2ecf20Sopenharmony_ci } 2898c2ecf20Sopenharmony_ci free(file); 2908c2ecf20Sopenharmony_ci return 1; 2918c2ecf20Sopenharmony_ci} 2928c2ecf20Sopenharmony_ci/* Check whether the file is a static library or not */ 2938c2ecf20Sopenharmony_cistatic int is_static_library(const char *objfile) 2948c2ecf20Sopenharmony_ci{ 2958c2ecf20Sopenharmony_ci int len = strlen(objfile); 2968c2ecf20Sopenharmony_ci if (objfile[len - 2] == '.' && objfile[len - 1] == 'a') 2978c2ecf20Sopenharmony_ci return 1; 2988c2ecf20Sopenharmony_ci else 2998c2ecf20Sopenharmony_ci return 0; 3008c2ecf20Sopenharmony_ci} 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci/* We have dir/file.o. Open dir/.file.o.cmd, look for source_ and deps_ line 3038c2ecf20Sopenharmony_ci * to figure out source files. */ 3048c2ecf20Sopenharmony_cistatic int parse_source_files(const char *objfile, struct md4_ctx *md) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci char *cmd, *file, *line, *dir, *pos; 3078c2ecf20Sopenharmony_ci const char *base; 3088c2ecf20Sopenharmony_ci int dirlen, ret = 0, check_files = 0; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd"))); 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci base = strrchr(objfile, '/'); 3138c2ecf20Sopenharmony_ci if (base) { 3148c2ecf20Sopenharmony_ci base++; 3158c2ecf20Sopenharmony_ci dirlen = base - objfile; 3168c2ecf20Sopenharmony_ci sprintf(cmd, "%.*s.%s.cmd", dirlen, objfile, base); 3178c2ecf20Sopenharmony_ci } else { 3188c2ecf20Sopenharmony_ci dirlen = 0; 3198c2ecf20Sopenharmony_ci sprintf(cmd, ".%s.cmd", objfile); 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci dir = NOFAIL(malloc(dirlen + 1)); 3228c2ecf20Sopenharmony_ci strncpy(dir, objfile, dirlen); 3238c2ecf20Sopenharmony_ci dir[dirlen] = '\0'; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci file = read_text_file(cmd); 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci pos = file; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci /* Sum all files in the same dir or subdirs. */ 3308c2ecf20Sopenharmony_ci while ((line = get_line(&pos))) { 3318c2ecf20Sopenharmony_ci char* p; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci /* trim the leading spaces away */ 3348c2ecf20Sopenharmony_ci while (isspace(*line)) 3358c2ecf20Sopenharmony_ci line++; 3368c2ecf20Sopenharmony_ci p = line; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci if (strncmp(line, "source_", sizeof("source_")-1) == 0) { 3398c2ecf20Sopenharmony_ci p = strrchr(line, ' '); 3408c2ecf20Sopenharmony_ci if (!p) { 3418c2ecf20Sopenharmony_ci warn("malformed line: %s\n", line); 3428c2ecf20Sopenharmony_ci goto out_file; 3438c2ecf20Sopenharmony_ci } 3448c2ecf20Sopenharmony_ci p++; 3458c2ecf20Sopenharmony_ci if (!parse_file(p, md)) { 3468c2ecf20Sopenharmony_ci warn("could not open %s: %s\n", 3478c2ecf20Sopenharmony_ci p, strerror(errno)); 3488c2ecf20Sopenharmony_ci goto out_file; 3498c2ecf20Sopenharmony_ci } 3508c2ecf20Sopenharmony_ci continue; 3518c2ecf20Sopenharmony_ci } 3528c2ecf20Sopenharmony_ci if (strncmp(line, "deps_", sizeof("deps_")-1) == 0) { 3538c2ecf20Sopenharmony_ci check_files = 1; 3548c2ecf20Sopenharmony_ci continue; 3558c2ecf20Sopenharmony_ci } 3568c2ecf20Sopenharmony_ci if (!check_files) 3578c2ecf20Sopenharmony_ci continue; 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci /* Continue until line does not end with '\' */ 3608c2ecf20Sopenharmony_ci if ( *(p + strlen(p)-1) != '\\') 3618c2ecf20Sopenharmony_ci break; 3628c2ecf20Sopenharmony_ci /* Terminate line at first space, to get rid of final ' \' */ 3638c2ecf20Sopenharmony_ci while (*p) { 3648c2ecf20Sopenharmony_ci if (isspace(*p)) { 3658c2ecf20Sopenharmony_ci *p = '\0'; 3668c2ecf20Sopenharmony_ci break; 3678c2ecf20Sopenharmony_ci } 3688c2ecf20Sopenharmony_ci p++; 3698c2ecf20Sopenharmony_ci } 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci /* Check if this file is in same dir as objfile */ 3728c2ecf20Sopenharmony_ci if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) { 3738c2ecf20Sopenharmony_ci if (!parse_file(line, md)) { 3748c2ecf20Sopenharmony_ci warn("could not open %s: %s\n", 3758c2ecf20Sopenharmony_ci line, strerror(errno)); 3768c2ecf20Sopenharmony_ci goto out_file; 3778c2ecf20Sopenharmony_ci } 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci } 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci } 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci /* Everyone parsed OK */ 3848c2ecf20Sopenharmony_ci ret = 1; 3858c2ecf20Sopenharmony_ciout_file: 3868c2ecf20Sopenharmony_ci free(file); 3878c2ecf20Sopenharmony_ci free(dir); 3888c2ecf20Sopenharmony_ci free(cmd); 3898c2ecf20Sopenharmony_ci return ret; 3908c2ecf20Sopenharmony_ci} 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci/* Calc and record src checksum. */ 3938c2ecf20Sopenharmony_civoid get_src_version(const char *modname, char sum[], unsigned sumlen) 3948c2ecf20Sopenharmony_ci{ 3958c2ecf20Sopenharmony_ci char *buf, *pos, *firstline; 3968c2ecf20Sopenharmony_ci struct md4_ctx md; 3978c2ecf20Sopenharmony_ci char *fname; 3988c2ecf20Sopenharmony_ci char filelist[PATH_MAX + 1]; 3998c2ecf20Sopenharmony_ci int postfix_len = 1; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci if (strends(modname, ".lto.o")) 4028c2ecf20Sopenharmony_ci postfix_len = 5; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci /* objects for a module are listed in the first line of *.mod file. */ 4058c2ecf20Sopenharmony_ci snprintf(filelist, sizeof(filelist), "%.*smod", 4068c2ecf20Sopenharmony_ci (int)strlen(modname) - postfix_len, modname); 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci buf = read_text_file(filelist); 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci pos = buf; 4118c2ecf20Sopenharmony_ci firstline = get_line(&pos); 4128c2ecf20Sopenharmony_ci if (!firstline) { 4138c2ecf20Sopenharmony_ci warn("bad ending versions file for %s\n", modname); 4148c2ecf20Sopenharmony_ci goto free; 4158c2ecf20Sopenharmony_ci } 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci md4_init(&md); 4188c2ecf20Sopenharmony_ci while ((fname = strsep(&firstline, " "))) { 4198c2ecf20Sopenharmony_ci if (!*fname) 4208c2ecf20Sopenharmony_ci continue; 4218c2ecf20Sopenharmony_ci if (!(is_static_library(fname)) && 4228c2ecf20Sopenharmony_ci !parse_source_files(fname, &md)) 4238c2ecf20Sopenharmony_ci goto free; 4248c2ecf20Sopenharmony_ci } 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci md4_final_ascii(&md, sum, sumlen); 4278c2ecf20Sopenharmony_cifree: 4288c2ecf20Sopenharmony_ci free(buf); 4298c2ecf20Sopenharmony_ci} 430