diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/test/shell/bazel/embedded_tools_deps_test.sh | 5 | ||||
-rw-r--r-- | src/test/shell/bazel/testdata/embedded_tools_srcs_deps | 2 | ||||
-rw-r--r-- | src/tools/singlejar/BUILD | 33 | ||||
-rw-r--r-- | src/tools/singlejar/diag.h | 20 | ||||
-rw-r--r-- | src/tools/singlejar/mapped_file.h | 70 | ||||
-rw-r--r-- | src/tools/singlejar/mapped_file_posix.inc | 74 | ||||
-rw-r--r-- | src/tools/singlejar/mapped_file_windows.inc | 48 | ||||
-rw-r--r-- | src/tools/singlejar/output_jar.cc | 1 | ||||
-rw-r--r-- | src/tools/singlejar/zip_headers.h | 38 |
9 files changed, 210 insertions, 81 deletions
diff --git a/src/test/shell/bazel/embedded_tools_deps_test.sh b/src/test/shell/bazel/embedded_tools_deps_test.sh index f609af82ca..27e13caac6 100755 --- a/src/test/shell/bazel/embedded_tools_deps_test.sh +++ b/src/test/shell/bazel/embedded_tools_deps_test.sh @@ -39,16 +39,17 @@ fi # using the output of genquery //src/test/shell/bazel:embedded_tools_deps # and removing everything under @bazel_tools because the exact contents of the # latter depends on the bazel binary used to run the test. +# Sort the targets for a deterministic diffing experience. current_deps="${TEST_TMPDIR}/current_deps" grep -v "^@bazel_tools//" \ "${TEST_SRCDIR}/io_bazel/src/test/shell/bazel/embedded_tools_deps" \ - >"${current_deps}" + | sort >"${current_deps}" # Load the current allowed dependencies of //src:embedded_tools_srcs allowed_deps=${testdata_path}/embedded_tools_srcs_deps diff_result=$(diff -ay --suppress-common-lines ${current_deps} \ - ${allowed_deps}) || \ + <(sort ${allowed_deps})) || \ fail "Dependencies of //src:embedded_tools_srcs are modified. The diff \ between the new dependencies and the current allowed dependencies is \ $(printf "\n${diff_result}\nThe new dependencies are ")$(cat ${current_deps})" diff --git a/src/test/shell/bazel/testdata/embedded_tools_srcs_deps b/src/test/shell/bazel/testdata/embedded_tools_srcs_deps index 277d524408..6bc26742d5 100644 --- a/src/test/shell/bazel/testdata/embedded_tools_srcs_deps +++ b/src/test/shell/bazel/testdata/embedded_tools_srcs_deps @@ -16,6 +16,8 @@ //src/tools/singlejar:token_stream //src/tools/singlejar:input_jar //src/tools/singlejar:combiners +//src/tools/singlejar:diag +//src/tools/singlejar:mapped_file //third_party/zlib:zlib //src/tools/launcher:launcher //src/tools/launcher:python_launcher diff --git a/src/tools/singlejar/BUILD b/src/tools/singlejar/BUILD index 3545e1f6e1..72f15c1f24 100644 --- a/src/tools/singlejar/BUILD +++ b/src/tools/singlejar/BUILD @@ -25,6 +25,8 @@ filegroup( "input_jar.cc", "input_jar.h", "mapped_file.h", + "mapped_file_posix.inc", + "mapped_file_windows.inc", "options.cc", "options.h", "output_jar.cc", @@ -289,27 +291,46 @@ cc_library( ) cc_library( + name = "diag", + hdrs = ["diag.h"], + visibility = ["//visibility:private"], +) + +cc_library( + name = "mapped_file", + srcs = select({ + "//src:windows": ["mapped_file_windows.inc"], + "//conditions:default": ["mapped_file_posix.inc"], + }), + hdrs = ["mapped_file.h"], + visibility = ["//visibility:private"], + deps = [":diag"], +) + +cc_library( name = "input_jar", srcs = [ - "diag.h", "input_jar.cc", - "mapped_file.h", ], hdrs = [ "input_jar.h", "zip_headers.h", ], + deps = [ + ":diag", + ":mapped_file", + ], ) cc_library( name = "options", srcs = [ - "diag.h", "options.cc", "options.h", ], hdrs = ["options.h"], deps = [ + ":diag", ":token_stream", ], ) @@ -317,8 +338,6 @@ cc_library( cc_library( name = "output_jar", srcs = [ - "diag.h", - "mapped_file.h", "output_jar.cc", "output_jar.h", ":zip_headers", @@ -326,7 +345,9 @@ cc_library( hdrs = ["output_jar.h"], deps = [ ":combiners", + ":diag", ":input_jar", + ":mapped_file", ":options", "//src/main/cpp/util", "//third_party/zlib", @@ -345,8 +366,8 @@ cc_library( cc_library( name = "token_stream", - srcs = ["diag.h"], hdrs = ["token_stream.h"], + deps = [":diag"], ) filegroup( diff --git a/src/tools/singlejar/diag.h b/src/tools/singlejar/diag.h index 775ab05344..cae255f15f 100644 --- a/src/tools/singlejar/diag.h +++ b/src/tools/singlejar/diag.h @@ -33,16 +33,18 @@ #include <string.h> #include <windows.h> #define _diag_msg(prefix, msg, ...) \ - { fprintf(stderr, prefix " [" __FILE__ ":%d]" msg, __LINE__, __VA_ARGS__); } -#define _diag_msgx(eval, prefix, msg, ...) \ - { \ - _diag_msg(prefix, msg, __VA_ARGS__); \ - ::ExitProcess(eval); \ + { fprintf(stderr, prefix msg, __VA_ARGS__); } +#define _diag_msgx(exit_value, prefix, msg, ...) \ + { \ + _diag_msg(prefix, msg, __VA_ARGS__); \ + ::ExitProcess(exit_value); \ } -#define diag_err(eval, fmt, ...) _diag_msgx(eval, "ERROR", fmt, __VA_ARGS__) -#define diag_errx(eval, ...) _diag_msgx(eval, "ERROR", "", __VA_ARGS__) -#define diag_warn(...) _diag_msg("WARNING", __VA_ARGS__) -#define diag_warnx(...) _diag_msg("WARNING") +#define diag_err(exit_value, fmt, ...) \ + _diag_msgx(exit_value, "ERROR: ", fmt, __VA_ARGS__) +#define diag_errx(exit_value, fmt, ...) \ + _diag_msgx(exit_value, "ERROR: ", fmt, __VA_ARGS__) +#define diag_warn(fmt, ...) _diag_msg("WARNING: ", fmt, __VA_ARGS__) +#define diag_warnx(fmt, ...) _diag_msg("WARNING: ", fmt, __VA_ARGS__) #else #error Unknown platform diff --git a/src/tools/singlejar/mapped_file.h b/src/tools/singlejar/mapped_file.h index b6c5e346fe..610ad46969 100644 --- a/src/tools/singlejar/mapped_file.h +++ b/src/tools/singlejar/mapped_file.h @@ -15,15 +15,8 @@ #ifndef BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_H_ #define BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_H_ 1 -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <unistd.h> - #include <string> -#include "src/tools/singlejar/diag.h" - /* * A mapped read-only file with auto closing. * @@ -32,55 +25,22 @@ * MappedFile::Close deletes the mapping. The destructor calls it, too. * A predictable set of methods provide conversion between file offsets and * mapped addresses, returns map size, etc. - * - * The implementation is 64-bit Linux or OSX specific. */ -#if !((defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)) && \ - __SIZEOF_POINTER__ == 8) -#error This code for 64 bit Unix. -#endif - class MappedFile { public: - MappedFile() : mapped_start_(nullptr), mapped_end_(nullptr), fd_(-1) {} +#ifdef COMPILER_MSVC + typedef /* HANDLE = void* */ void *FileHandleType; +#else // not COMPILER_MSVC + typedef int FileHandleType; +#endif // COMPILER_MSVC + + MappedFile(); ~MappedFile() { Close(); } - bool Open(const std::string& path) { - if (is_open()) { - diag_errx(1, "%s:%d: This instance is already open", __FILE__, __LINE__); - } - if ((fd_ = open(path.c_str(), O_RDONLY)) < 0) { - diag_warn("%s:%d: open %s:", __FILE__, __LINE__, path.c_str()); - return false; - } - // Map the file, even if it is empty (in which case allocate 1 byte to it). - struct stat st; - if (fstat(fd_, &st) || - (mapped_start_ = static_cast<unsigned char *>( - mmap(nullptr, st.st_size ? st.st_size : 1, PROT_READ, MAP_PRIVATE, - fd_, 0))) == MAP_FAILED) { - if (S_ISDIR(st.st_mode)) { - diag_warn("%s:%d: %s is a directory", __FILE__, __LINE__, path.c_str()); - } else { - diag_warn("%s:%d: mmap %s:", __FILE__, __LINE__, path.c_str()); - } - close(fd_); - fd_ = -1; - return false; - } - mapped_end_ = mapped_start_ + st.st_size; - return true; - } + bool Open(const std::string &path); - void Close() { - if (is_open()) { - munmap(mapped_start_, mapped_end_ - mapped_start_); - mapped_start_ = mapped_end_ = nullptr; - close(fd_); - fd_ = -1; - } - } + void Close(); bool mapped(const void *addr) const { return mapped_start_ <= addr && addr < mapped_end_; @@ -94,14 +54,20 @@ class MappedFile { off_t offset(const void *address) const { return reinterpret_cast<const unsigned char *>(address) - mapped_start_; } - int fd() const { return fd_; } + FileHandleType fd() const { return fd_; } size_t size() const { return mapped_end_ - mapped_start_; } - bool is_open() { return fd_ >= 0; } + bool is_open() const; private: unsigned char *mapped_start_; unsigned char *mapped_end_; - int fd_; + FileHandleType fd_; }; +#ifdef COMPILER_MSVC +#include "src/tools/singlejar/mapped_file_windows.inc" +#else // not COMPILER_MSVC +#include "src/tools/singlejar/mapped_file_posix.inc" +#endif // COMPILER_MSVC + #endif // BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_H_ diff --git a/src/tools/singlejar/mapped_file_posix.inc b/src/tools/singlejar/mapped_file_posix.inc new file mode 100644 index 0000000000..ad6c6a5310 --- /dev/null +++ b/src/tools/singlejar/mapped_file_posix.inc @@ -0,0 +1,74 @@ +// Copyright 2018 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_POSIX_H_ +#define BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_POSIX_H_ 1 + +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <string> + +#include "src/tools/singlejar/diag.h" + +// The implementation is 64-bit Linux or OSX specific. +#if !((defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)) && \ + __SIZEOF_POINTER__ == 8) +#error This code for 64 bit Unix. +#endif + +inline MappedFile::MappedFile() + : mapped_start_(nullptr), mapped_end_(nullptr), fd_(-1) {} + +inline bool MappedFile::Open(const std::string& path) { + if (is_open()) { + diag_errx(1, "%s:%d: This instance is already open", __FILE__, __LINE__); + } + if ((fd_ = open(path.c_str(), O_RDONLY)) < 0) { + diag_warn("%s:%d: open %s:", __FILE__, __LINE__, path.c_str()); + return false; + } + // Map the file, even if it is empty (in which case allocate 1 byte to it). + struct stat st; + if (fstat(fd_, &st) || + (mapped_start_ = static_cast<unsigned char *>( + mmap(nullptr, st.st_size ? st.st_size : 1, PROT_READ, MAP_PRIVATE, + fd_, 0))) == MAP_FAILED) { + if (S_ISDIR(st.st_mode)) { + diag_warn("%s:%d: %s is a directory", __FILE__, __LINE__, path.c_str()); + } else { + diag_warn("%s:%d: mmap %s:", __FILE__, __LINE__, path.c_str()); + } + close(fd_); + fd_ = -1; + return false; + } + mapped_end_ = mapped_start_ + st.st_size; + return true; +} + +inline void MappedFile::Close() { + if (is_open()) { + munmap(mapped_start_, mapped_end_ - mapped_start_); + mapped_start_ = mapped_end_ = nullptr; + close(fd_); + fd_ = -1; + } +} + +inline bool MappedFile::is_open() const { return fd_ >= 0; } + +#endif // BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_POSIX_H_ diff --git a/src/tools/singlejar/mapped_file_windows.inc b/src/tools/singlejar/mapped_file_windows.inc new file mode 100644 index 0000000000..5875149766 --- /dev/null +++ b/src/tools/singlejar/mapped_file_windows.inc @@ -0,0 +1,48 @@ +// Copyright 2018 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_WINDOWS_H_ +#define BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_WINDOWS_H_ 1 + +#if !defined(COMPILER_MSVC) || !defined(_WIN64) +#error This code is for 64 bit Windows. +#endif + +#include <windows.h> + +#include <string> + +typedef HANDLE FileHandleType; + +inline MappedFile::MappedFile() + : mapped_start_(nullptr), mapped_end_(nullptr), fd_(INVALID_HANDLE_VALUE) {} + +inline bool MappedFile::Open(const std::string& path) { + // TODO(laszlocsomor): implement as part of + // https://github.com/bazelbuild/bazel/issues/2241 + return false; +} + +inline void MappedFile::Close() { + // TODO(laszlocsomor): implement as part of + // https://github.com/bazelbuild/bazel/issues/2241 +} + +inline bool MappedFile::is_open() const { + // TODO(laszlocsomor): implement as part of + // https://github.com/bazelbuild/bazel/issues/2241 + return false; +} + +#endif // BAZEL_SRC_TOOLS_SINGLEJAR_MAPPED_FILE_WINDOWS_H_
\ No newline at end of file diff --git a/src/tools/singlejar/output_jar.cc b/src/tools/singlejar/output_jar.cc index b80940eb0a..f0323478f3 100644 --- a/src/tools/singlejar/output_jar.cc +++ b/src/tools/singlejar/output_jar.cc @@ -19,6 +19,7 @@ #include <err.h> #include <errno.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> diff --git a/src/tools/singlejar/zip_headers.h b/src/tools/singlejar/zip_headers.h index 0b3202973a..6d10cc26e5 100644 --- a/src/tools/singlejar/zip_headers.h +++ b/src/tools/singlejar/zip_headers.h @@ -29,8 +29,8 @@ #include <endian.h> #elif defined(__FreeBSD__) #include <sys/endian.h> -#elif defined(__APPLE__) -// Hopefully OSX will keep running solely on little endian CPUs, so: +#elif defined(__APPLE__) || defined(COMPILER_MSVC) +// Hopefully OSX and Windows will keep running solely on little endian CPUs, so: #define le16toh(x) (x) #define le32toh(x) (x) #define le64toh(x) (x) @@ -44,6 +44,13 @@ #include <string> #include <type_traits> +#ifdef COMPILER_MSVC +#pragma pack(push, 1) +#define attr_packed +#else +#define attr_packed __attribute__((packed)) +#endif + class ziph { public: static const uint8_t *byte_ptr(const void *ptr) { @@ -116,7 +123,8 @@ class ExtraField { protected: uint16_t tag_; uint16_t payload_size_; -} __attribute__((packed)); +} attr_packed; + static_assert(4 == sizeof(ExtraField), "ExtraField class fields layout is incorrect."); @@ -149,7 +157,7 @@ class Zip64ExtraField : public ExtraField { int attr_count() const { return payload_size() / sizeof(attr_[0]); } void attr_count(int n) { payload_size(n * sizeof(attr_[0])); } - // Space needed for this field to accomodate n_attr attributes + // Space needed for this field to accommodate n_attr attributes static uint16_t space_needed(int n_attrs) { return n_attrs > 0 ? sizeof(Zip64ExtraField) + n_attrs * sizeof(uint64_t) : 0; @@ -157,7 +165,7 @@ class Zip64ExtraField : public ExtraField { private: uint64_t attr_[]; -} __attribute__((packed)); +} attr_packed; static_assert(4 == sizeof(Zip64ExtraField), "Zip64ExtraField class fields layout is incorrect."); @@ -194,7 +202,7 @@ class UnixTimeExtraField : public ExtraField { private: uint8_t flags_; uint32_t timestamp_[]; -} __attribute__((packed)); +} attr_packed; static_assert(5 == sizeof(UnixTimeExtraField), "UnixTimeExtraField layout is incorrect"); @@ -318,7 +326,7 @@ class LH { uint16_t extra_fields_length_; char file_name_[0]; // Followed by extra_fields. -} __attribute__((packed)); +} attr_packed; static_assert(30 == sizeof(LH), "The fields layout for class LH is incorrect"); /* Data descriptor Record: @@ -359,7 +367,7 @@ class DDR { private: uint32_t optional_signature_; -} __attribute__((packed)); +} attr_packed; /* Central Directory Header. */ class CDH { @@ -519,7 +527,7 @@ class CDH { uint32_t local_header_offset32_; char file_name_[0]; // Followed by extra fields and then comment. -} __attribute__((packed)); +} attr_packed; static_assert(46 == sizeof(CDH), "Class CDH fields layout is incorrect."); /* Zip64 End of Central Directory Locator. */ @@ -542,7 +550,7 @@ class ECD64Locator { uint32_t ecd64_disk_nr_; uint64_t ecd64_offset_; uint32_t total_disks_; -} __attribute__((packed)); +} attr_packed; static_assert(20 == sizeof(ECD64Locator), "ECD64Locator class fields layout is incorrect."); @@ -595,7 +603,7 @@ class ECD { uint32_t cen_offset32_; uint16_t comment_length_; uint8_t comment_[0]; -} __attribute__((packed)); +} attr_packed; static_assert(22 == sizeof(ECD), "ECD class fields layout is incorrect."); /* Zip64 end of central directory. */ @@ -642,7 +650,13 @@ class ECD64 { uint64_t total_entries_; uint64_t cen_size_; uint64_t cen_offset_; -} __attribute__((packed)); +} attr_packed; static_assert(56 == sizeof(ECD64), "ECD64 class fields layout is incorrect."); +#ifdef COMPILER_MSVC +#pragma pack(pop) +#endif + +#undef attr_packed + #endif // BAZEL_SRC_TOOLS_SINGLEJAR_ZIP_HEADERS_H_ |