aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2017-08-01 02:03:52 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2017-08-01 02:03:52 +0000
commit1db06faa3891bd056431a5aa8f27c5bc34ad7988 (patch)
tree34534e0d9ab0152ab0b095145df9d57e7c4d17e4 /tools
parent4dd33f92d82b9fb77152bfc68f312d2fa5710a28 (diff)
parentb97049c0390cb1a11b9cb0b14391972e69398ce5 (diff)
downloadandroid_bionic-1db06faa3891bd056431a5aa8f27c5bc34ad7988.tar.gz
android_bionic-1db06faa3891bd056431a5aa8f27c5bc34ad7988.tar.bz2
android_bionic-1db06faa3891bd056431a5aa8f27c5bc34ad7988.zip
Merge "libc: Split FORTIFY into its own headers"
Diffstat (limited to 'tools')
-rw-r--r--tools/versioner/src/Utils.cpp27
-rw-r--r--tools/versioner/src/Utils.h4
-rw-r--r--tools/versioner/src/versioner.cpp74
3 files changed, 76 insertions, 29 deletions
diff --git a/tools/versioner/src/Utils.cpp b/tools/versioner/src/Utils.cpp
index ef7facc08..ca186a461 100644
--- a/tools/versioner/src/Utils.cpp
+++ b/tools/versioner/src/Utils.cpp
@@ -37,7 +37,8 @@ std::string getWorkingDir() {
return buf;
}
-std::vector<std::string> collectHeaders(const std::string& directory) {
+std::vector<std::string> collectHeaders(const std::string& directory,
+ const std::unordered_set<std::string>& ignored_directories) {
std::vector<std::string> headers;
char* dir_argv[2] = { const_cast<char*>(directory.c_str()), nullptr };
@@ -48,16 +49,34 @@ std::vector<std::string> collectHeaders(const std::string& directory) {
err(1, "failed to open directory '%s'", directory.c_str());
}
+ FTSENT* skipping = nullptr;
while (FTSENT* ent = fts_read(fts.get())) {
- if (ent->fts_info & (FTS_D | FTS_DP)) {
+ if (ent->fts_info & FTS_DP) {
+ if (ent == skipping) {
+ skipping = nullptr;
+ }
continue;
}
- if (!android::base::EndsWith(ent->fts_path, ".h")) {
+ if (skipping != nullptr) {
continue;
}
- headers.push_back(ent->fts_path);
+ if (ent->fts_info & FTS_D) {
+ if (ignored_directories.count(ent->fts_path) != 0) {
+ // fts_read guarantees that `ent` is valid and sane to hold on to until
+ // after it's returned with FTS_DP set.
+ skipping = ent;
+ }
+ continue;
+ }
+
+ std::string path = ent->fts_path;
+ if (!android::base::EndsWith(path, ".h")) {
+ continue;
+ }
+
+ headers.push_back(std::move(path));
}
return headers;
diff --git a/tools/versioner/src/Utils.h b/tools/versioner/src/Utils.h
index 44a34f832..9b45dcd49 100644
--- a/tools/versioner/src/Utils.h
+++ b/tools/versioner/src/Utils.h
@@ -22,12 +22,14 @@
#include <unistd.h>
#include <string>
+#include <unordered_set>
#include <vector>
#include <llvm/ADT/StringRef.h>
std::string getWorkingDir();
-std::vector<std::string> collectHeaders(const std::string& directory);
+std::vector<std::string> collectHeaders(const std::string& directory,
+ const std::unordered_set<std::string>& ignored_directories);
static inline std::string dirname(const std::string& path) {
std::unique_ptr<char, decltype(&free)> path_copy(strdup(path.c_str()), free);
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index 747c767d5..8db75d7ec 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -45,6 +45,7 @@
#include <android-base/file.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
+#include <android-base/strings.h>
#include "Arch.h"
#include "DeclarationDatabase.h"
@@ -79,11 +80,21 @@ static int getCpuCount() {
#endif
}
-static CompilationRequirements collectRequirements(const Arch& arch, const std::string& header_dir,
- const std::string& dependency_dir) {
- std::vector<std::string> headers = collectHeaders(header_dir);
- std::vector<std::string> dependencies = { header_dir };
- if (!dependency_dir.empty()) {
+namespace {
+struct HeaderLocationInformation {
+ std::string header_dir;
+ std::string dependency_dir;
+ // Absolute paths to ignore all children -- including subdirectories -- of.
+ std::unordered_set<std::string> ignored_directories;
+};
+}
+
+static CompilationRequirements collectRequirements(const Arch& arch,
+ const HeaderLocationInformation& location) {
+ std::vector<std::string> headers =
+ collectHeaders(location.header_dir, location.ignored_directories);
+ std::vector<std::string> dependencies = { location.header_dir };
+ if (!location.dependency_dir.empty()) {
auto collect_children = [&dependencies](const std::string& dir_path) {
DIR* dir = opendir(dir_path.c_str());
if (!dir) {
@@ -114,8 +125,8 @@ static CompilationRequirements collectRequirements(const Arch& arch, const std::
closedir(dir);
};
- collect_children(dependency_dir + "/common");
- collect_children(dependency_dir + "/" + to_string(arch));
+ collect_children(location.dependency_dir + "/common");
+ collect_children(location.dependency_dir + "/" + to_string(arch));
}
auto new_end = std::remove_if(headers.begin(), headers.end(), [&arch](llvm::StringRef header) {
@@ -159,13 +170,12 @@ static std::set<CompilationType> generateCompilationTypes(const std::set<Arch> s
}
static std::unique_ptr<HeaderDatabase> compileHeaders(const std::set<CompilationType>& types,
- const std::string& header_dir,
- const std::string& dependency_dir) {
+ const HeaderLocationInformation& location) {
if (types.empty()) {
errx(1, "compileHeaders received no CompilationTypes");
}
- auto vfs = createCommonVFS(header_dir, dependency_dir, add_include);
+ auto vfs = createCommonVFS(location.header_dir, location.dependency_dir, add_include);
size_t thread_count = max_thread_count;
std::vector<std::thread> threads;
@@ -176,7 +186,7 @@ static std::unique_ptr<HeaderDatabase> compileHeaders(const std::set<Compilation
auto result = std::make_unique<HeaderDatabase>();
for (const auto& type : types) {
if (requirements.count(type.arch) == 0) {
- requirements[type.arch] = collectRequirements(type.arch, header_dir, dependency_dir);
+ requirements[type.arch] = collectRequirements(type.arch, location);
}
}
@@ -454,6 +464,7 @@ static void usage(bool help = false) {
fprintf(stderr, " -f\t\tpreprocess header files even if validation fails\n");
fprintf(stderr, "\n");
fprintf(stderr, "Miscellaneous:\n");
+ fprintf(stderr, " -F\t\tdo not ignore FORTIFY headers by default\n");
fprintf(stderr, " -d\t\tdump function availability\n");
fprintf(stderr, " -j THREADS\tmaximum number of threads to use\n");
fprintf(stderr, " -v\t\tenable verbose logging\n");
@@ -477,9 +488,10 @@ int main(int argc, char** argv) {
std::string preprocessor_output_path;
bool force = false;
bool dump = false;
+ bool ignore_fortify_headers = true;
int c;
- while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhi")) != -1) {
+ while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhFi")) != -1) {
default_args = false;
switch (c) {
case 'a': {
@@ -565,6 +577,10 @@ int main(int argc, char** argv) {
add_include = true;
break;
+ case 'F':
+ ignore_fortify_headers = false;
+ break;
+
default:
usage();
break;
@@ -575,8 +591,7 @@ int main(int argc, char** argv) {
usage();
}
- std::string header_dir;
- std::string dependency_dir;
+ HeaderLocationInformation location;
const char* top = getenv("ANDROID_BUILD_TOP");
if (!top && (optind == argc || add_include)) {
@@ -587,19 +602,30 @@ int main(int argc, char** argv) {
if (optind == argc) {
// Neither HEADER_PATH nor DEPS_PATH were specified, so try to figure them out.
std::string versioner_dir = to_string(top) + "/bionic/tools/versioner";
- header_dir = versioner_dir + "/current";
- dependency_dir = versioner_dir + "/dependencies";
+ location.header_dir = versioner_dir + "/current";
+ location.dependency_dir = versioner_dir + "/dependencies";
if (platform_dir.empty()) {
platform_dir = versioner_dir + "/platforms";
}
} else {
- if (!android::base::Realpath(argv[optind], &header_dir)) {
+ if (!android::base::Realpath(argv[optind], &location.header_dir)) {
err(1, "failed to get realpath for path '%s'", argv[optind]);
}
if (argc - optind == 2) {
- dependency_dir = argv[optind + 1];
+ location.dependency_dir = argv[optind + 1];
+ }
+ }
+
+ // Every file that lives in bits/fortify is logically a part of a header outside of bits/fortify.
+ // This makes the files there impossible to build on their own.
+ if (ignore_fortify_headers) {
+ std::string fortify_path = location.header_dir;
+ if (!android::base::EndsWith(location.header_dir, "/")) {
+ fortify_path += '/';
}
+ fortify_path += "bits/fortify";
+ location.ignored_directories.insert(std::move(fortify_path));
}
if (selected_levels.empty()) {
@@ -612,10 +638,10 @@ int main(int argc, char** argv) {
struct stat st;
- if (stat(header_dir.c_str(), &st) != 0) {
- err(1, "failed to stat '%s'", header_dir.c_str());
+ if (const char *dir = location.header_dir.c_str(); stat(dir, &st) != 0) {
+ err(1, "failed to stat '%s'", dir);
} else if (!S_ISDIR(st.st_mode)) {
- errx(1, "'%s' is not a directory", header_dir.c_str());
+ errx(1, "'%s' is not a directory", dir);
}
std::set<CompilationType> compilation_types;
@@ -631,7 +657,7 @@ int main(int argc, char** argv) {
auto start = std::chrono::high_resolution_clock::now();
std::unique_ptr<HeaderDatabase> declaration_database =
- compileHeaders(compilation_types, header_dir, dependency_dir);
+ compileHeaders(compilation_types, location);
auto end = std::chrono::high_resolution_clock::now();
if (verbose) {
@@ -641,7 +667,7 @@ int main(int argc, char** argv) {
bool failed = false;
if (dump) {
- declaration_database->dump(header_dir + "/");
+ declaration_database->dump(location.header_dir + "/");
} else {
if (!sanityCheck(declaration_database.get())) {
printf("versioner: sanity check failed\n");
@@ -657,7 +683,7 @@ int main(int argc, char** argv) {
}
if (!preprocessor_output_path.empty() && (force || !failed)) {
- failed = !preprocessHeaders(preprocessor_output_path, header_dir, declaration_database.get());
+ failed = !preprocessHeaders(preprocessor_output_path, location.header_dir, declaration_database.get());
}
return failed;
}