diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2017-08-01 02:03:52 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-08-01 02:03:52 +0000 |
commit | 1db06faa3891bd056431a5aa8f27c5bc34ad7988 (patch) | |
tree | 34534e0d9ab0152ab0b095145df9d57e7c4d17e4 /tools | |
parent | 4dd33f92d82b9fb77152bfc68f312d2fa5710a28 (diff) | |
parent | b97049c0390cb1a11b9cb0b14391972e69398ce5 (diff) | |
download | android_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.cpp | 27 | ||||
-rw-r--r-- | tools/versioner/src/Utils.h | 4 | ||||
-rw-r--r-- | tools/versioner/src/versioner.cpp | 74 |
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; } |