]>
sourceware.org Git - systemtap.git/blob - hash.cxx
1 // Copyright (C) Andrew Tridgell 2002 (original file)
2 // Copyright (C) 2006-2007 Red Hat Inc. (systemtap changes)
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <sys/types.h>
44 hash::add(const unsigned char *buffer
, size_t size
)
46 mdfour_update(&md4
, buffer
, size
);
51 hash::result(string
& r
)
53 ostringstream rstream
;
54 unsigned char sum
[16];
56 mdfour_update(&md4
, NULL
, 0);
57 mdfour_result(&md4
, sum
);
59 for (int i
=0; i
<16; i
++)
61 rstream
<< hex
<< setfill('0') << setw(2) << (unsigned)sum
[i
];
63 rstream
<< "_" << setw(0) << dec
<< (unsigned)md4
.totalN
;
69 find_hash (systemtap_session
& s
, const string
& script
)
75 // We use a N level subdir for the cache path. Let N be adjustable.
77 if ((s_n
= getenv("SYSTEMTAP_NLEVELS")))
80 if (nlevels
< 1) nlevels
= 1;
81 if (nlevels
> 8) nlevels
= 8;
84 // Hash getuid. This really shouldn't be necessary (since who you
85 // are doesn't change the generated output), but the hash gets used
86 // as the module name. If two different users try to run the same
87 // script at the same time, we need something to differentiate the
91 // Hash kernel release and arch.
92 h
.add(s
.kernel_release
);
93 h
.add(s
.architecture
);
95 // Hash user-specified arguments (that change the generated module).
96 h
.add(s
.bulk_mode
); // '-b'
97 h
.add(s
.merge
); // '-M'
98 h
.add(s
.timing
); // '-t'
99 h
.add(s
.prologue_searching
); // '-P'
100 for (unsigned i
= 0; i
< s
.macros
.size(); i
++)
103 // Hash runtime path (that gets added in as "-I path").
104 h
.add(s
.runtime_path
);
106 // Hash compiler path, size, and mtime. We're just going to assume
107 // we'll be using gcc, which should be correct most of the time.
109 if (find_executable("gcc", gcc_path
))
111 if (stat(gcc_path
.c_str(), &st
) == 0)
119 // Hash the systemtap size and mtime. We could use VERSION/DATE,
120 // but when developing systemtap that doesn't work well (since you
121 // can compile systemtap multiple times in 1 day). Since we don't
122 // know exactly where we're getting run from, we'll use
124 if (stat("/proc/self/exe", &st
) == 0)
130 // Add in pass 2 script output.
133 // Use a N level subdir for the cache path to reduce the impact on
134 // filesystems which are slow for large directories.
135 string hashdir
= s
.cache_path
;
139 for (int i
= 0; i
< nlevels
; i
++)
141 hashdir
+= string("/") + result
[i
*2] + result
[i
*2 + 1];
142 if (create_dir(hashdir
.c_str()) != 0)
144 cerr
<< "Warning: failed to create cache directory (\""
145 << hashdir
+ "\"): " << strerror(errno
) << endl
;
146 cerr
<< "Disabling cache support." << endl
;
152 // Update module name to be 'stap_{hash start}'. '{hash start}'
153 // must not be too long. This shouldn't happen, since the maximum
154 // size of a hash is 32 fixed chars + 1 (for the '_') + a max of 11.
155 s
.module_name
= "stap_" + result
;
156 if (s
.module_name
.size() >= (MODULE_NAME_LEN
- 1))
157 s
.module_name
.resize(MODULE_NAME_LEN
- 1);
159 // 'ccache' would use a hash path of something like:
160 // s.hash_path = hashdir + "/" + result.substr(nlevels);
161 // which would look like:
162 // ~/.stap_cache/A/B/CDEFGHIJKLMNOPQRSTUVWXYZABCDEF_XXX
164 // We're using the following so that the module can be used straight
165 // from the cache if desired. This ends up looking like this:
166 // ~/.stap_cache/A/B/stap_ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF_XXX.ko
167 s
.hash_path
= hashdir
+ "/" + s
.module_name
+ ".ko";
169 // Update C source name with new module_name.
170 s
.translated_source
= string(s
.tmpdir
) + "/" + s
.module_name
+ ".c";
This page took 0.049125 seconds and 6 git commands to generate.