diff options
author | 2019-01-09 14:47:00 +0000 | |
---|---|---|
committer | 2019-01-10 15:48:13 +0000 | |
commit | fdb2f60e7ad3d676ec55286e29e11bc7506b1973 (patch) | |
tree | 103339655651dbcdaa89baf949f0a098dd7a647c | |
parent | 2ccc9c3f2a6318e15a7a1d63ece206a6a075fa19 (diff) |
Separate libdexfile external C ABI from the C++ header file.
Also add a test to compile it with C.
Test: m
Test: m test-art-{host,target}-gtest-dex_file_ext_c_test
Test: art/test/testrunner/run_build_test_target.py -j80 art-test
Bug: 120978655
Change-Id: I6e9944a2051bef9a2775bc2072df4e0ed81dc833
-rw-r--r-- | build/Android.gtest.mk | 1 | ||||
-rw-r--r-- | libdexfile/Android.bp | 70 | ||||
-rw-r--r-- | libdexfile/external/dex_file_ext.cc | 24 | ||||
-rw-r--r-- | libdexfile/external/dex_file_ext_c_test.c | 54 | ||||
-rw-r--r-- | libdexfile/external/include/art_api/dex_file_external.h | 89 | ||||
-rw-r--r-- | libdexfile/external/include/art_api/dex_file_support.h | 68 |
6 files changed, 198 insertions, 108 deletions
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk index a926d9a686..d95777f482 100644 --- a/build/Android.gtest.mk +++ b/build/Android.gtest.mk @@ -383,6 +383,7 @@ ART_TEST_MODULES := \ art_hiddenapi_tests \ art_imgdiag_tests \ art_libartbase_tests \ + art_libdexfile_external_tests \ art_libdexfile_tests \ art_libprofile_tests \ art_oatdump_tests \ diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp index 9c48aa2c1b..bc7a20bc8a 100644 --- a/libdexfile/Android.bp +++ b/libdexfile/Android.bp @@ -176,6 +176,36 @@ art_cc_library { }, } +art_cc_test { + name: "art_libdexfile_tests", + defaults: [ + "art_gtest_defaults", + ], + srcs: [ + "dex/art_dex_file_loader_test.cc", + "dex/class_accessor_test.cc", + "dex/code_item_accessors_test.cc", + "dex/compact_dex_file_test.cc", + "dex/compact_offset_table_test.cc", + "dex/descriptors_names_test.cc", + "dex/test_dex_file_builder_test.cc", + "dex/dex_file_loader_test.cc", + "dex/dex_file_verifier_test.cc", + "dex/dex_instruction_test.cc", + "dex/primitive_test.cc", + "dex/string_reference_test.cc", + "dex/type_lookup_table_test.cc", + "dex/utf_test.cc", + ], + shared_libs: [ + "libbacktrace", + "libziparchive", + ], + include_dirs: [ + "external/zlib", + ], +} + cc_library_headers { name: "libdexfile_external_headers", host_supported: true, @@ -227,6 +257,16 @@ cc_library { }, } +art_cc_test { + name: "art_libdexfile_external_tests", + host_supported: true, + test_per_src: true, // For consistency with other ART gtests. + srcs: [ + "external/dex_file_ext_c_test.c", + ], + header_libs: ["libdexfile_external_headers"], +} + // Support library with a C++ API for accessing the libdexfile API for external // (non-ART) users. They should link to their own instance of this (either // statically or through linker namespaces). @@ -240,33 +280,3 @@ cc_library { shared_libs: ["libdexfile_external"], export_header_lib_headers: ["libdexfile_external_headers"], } - -art_cc_test { - name: "art_libdexfile_tests", - defaults: [ - "art_gtest_defaults", - ], - srcs: [ - "dex/art_dex_file_loader_test.cc", - "dex/class_accessor_test.cc", - "dex/code_item_accessors_test.cc", - "dex/compact_dex_file_test.cc", - "dex/compact_offset_table_test.cc", - "dex/descriptors_names_test.cc", - "dex/test_dex_file_builder_test.cc", - "dex/dex_file_loader_test.cc", - "dex/dex_file_verifier_test.cc", - "dex/dex_instruction_test.cc", - "dex/primitive_test.cc", - "dex/string_reference_test.cc", - "dex/type_lookup_table_test.cc", - "dex/utf_test.cc", - ], - shared_libs: [ - "libbacktrace", - "libziparchive", - ], - include_dirs: [ - "external/zlib", - ], -} diff --git a/libdexfile/external/dex_file_ext.cc b/libdexfile/external/dex_file_ext.cc index 7bf01a8931..348ed60220 100644 --- a/libdexfile/external/dex_file_ext.cc +++ b/libdexfile/external/dex_file_ext.cc @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "art_api/dex_file_external.h" + #include <inttypes.h> #include <stdint.h> #include <sys/mman.h> @@ -39,18 +41,9 @@ #include <dex/dex_file-inl.h> #include <dex/dex_file_loader.h> -#include "art_api/dex_file_support.h" - -extern "C" class ExtDexFileString { - public: - const std::string str_; -}; - namespace art { namespace { -const ExtDexFileString empty_string{""}; - struct MethodCacheEntry { int32_t offset; // Offset relative to the start of the dex file header. int32_t len; @@ -77,9 +70,15 @@ class MappedFileContainer : public DexFileContainer { extern "C" { +struct ExtDexFileString { + const std::string str_; +}; + +static const ExtDexFileString empty_string{""}; + const ExtDexFileString* ExtDexFileMakeString(const char* str) { if (str[0] == '\0') { - return &art::empty_string; + return &empty_string; } return new ExtDexFileString{str}; } @@ -92,14 +91,15 @@ const char* ExtDexFileGetString(const ExtDexFileString* ext_string, /*out*/ size void ExtDexFileFreeString(const ExtDexFileString* ext_string) { DCHECK(ext_string != nullptr); - if (ext_string != &art::empty_string) { + if (ext_string != &empty_string) { delete (ext_string); } } // Wraps DexFile to add the caching needed by the external interface. This is // what gets passed over as ExtDexFile*. -class ExtDexFile { +struct ExtDexFile { + private: // Method cache for GetMethodInfoForOffset. This is populated as we iterate // sequentially through the class defs. MethodCacheEntry.name is only set for // methods returned by GetMethodInfoForOffset. diff --git a/libdexfile/external/dex_file_ext_c_test.c b/libdexfile/external/dex_file_ext_c_test.c new file mode 100644 index 0000000000..ad0737a292 --- /dev/null +++ b/libdexfile/external/dex_file_ext_c_test.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * 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. + */ + +#include <errno.h> +#include <stdio.h> +#include <string.h> + +/* The main purpose of this test is to ensure this C header compiles in C, so + * that no C++ features inadvertently leak into the C ABI. */ +#include "art_api/dex_file_external.h" + +static const char gtest_output_arg[] = "--gtest_output=xml:"; +static const char gtest_output_xml[] = "\ +<?xml version=\"1.0\"?>\n\ +<testsuites tests=\"0\" failures=\"0\" disabled=\"0\" errors=\"0\" name=\"AllTests\">"; + +/* Writes a dummy gtest xml report to the given path. */ +static int write_gtest_output_xml(char* gtest_output_path) { + FILE* output_fd = fopen(gtest_output_path, "w"); + if (output_fd == NULL) { + fprintf(stderr, "Failed to open %s: %s\n", gtest_output_path, strerror(errno)); + return 1; + } + if (fprintf(output_fd, gtest_output_xml) != sizeof(gtest_output_xml) - 1) { + fprintf(stderr, "Failed to write %s: %s\n", gtest_output_path, strerror(errno)); + return 1; + } + if (fclose(output_fd) != 0) { + fprintf(stderr, "Failed to close %s: %s\n", gtest_output_path, strerror(errno)); + return 1; + } + return 0; +} + +int main(int argc, char** argv) { + if (argc >= 1 && strncmp(argv[1], gtest_output_arg, sizeof(gtest_output_arg) - 1) == 0) { + /* The ART gtest framework expects all tests to understand --gtest_output. */ + return write_gtest_output_xml(argv[1] + sizeof(gtest_output_arg) - 1); + } + return 0; +} diff --git a/libdexfile/external/include/art_api/dex_file_external.h b/libdexfile/external/include/art_api/dex_file_external.h new file mode 100644 index 0000000000..b29235f9ab --- /dev/null +++ b/libdexfile/external/include/art_api/dex_file_external.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * 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 ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_EXTERNAL_H_ +#define ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_EXTERNAL_H_ + +// Dex file external API + +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// This is the stable C ABI that backs art_api::dex below. Structs and functions +// may only be added here. C++ users should use dex_file_support.h instead. + +// Opaque wrapper for an std::string allocated in libdexfile which must be freed +// using ExtDexFileFreeString. +struct ExtDexFileString; + +// Returns an ExtDexFileString initialized to the given string. +const struct ExtDexFileString* ExtDexFileMakeString(const char* str); + +// Returns a pointer to the underlying null-terminated character array and its +// size for the given ExtDexFileString. +const char* ExtDexFileGetString(const struct ExtDexFileString* ext_string, /*out*/ size_t* size); + +// Frees an ExtDexFileString. +void ExtDexFileFreeString(const struct ExtDexFileString* ext_string); + +struct ExtDexFileMethodInfo { + int32_t offset; + int32_t len; + const struct ExtDexFileString* name; +}; + +struct ExtDexFile; + +// See art_api::dex::DexFile::OpenFromMemory. Returns true on success. +int ExtDexFileOpenFromMemory(const void* addr, + /*inout*/ size_t* size, + const char* location, + /*out*/ const struct ExtDexFileString** error_msg, + /*out*/ struct ExtDexFile** ext_dex_file); + +// See art_api::dex::DexFile::OpenFromFd. Returns true on success. +int ExtDexFileOpenFromFd(int fd, + off_t offset, + const char* location, + /*out*/ const struct ExtDexFileString** error_msg, + /*out*/ struct ExtDexFile** ext_dex_file); + +// See art_api::dex::DexFile::GetMethodInfoForOffset. Returns true on success. +int ExtDexFileGetMethodInfoForOffset(struct ExtDexFile* ext_dex_file, + int64_t dex_offset, + int with_signature, + /*out*/ struct ExtDexFileMethodInfo* method_info); + +typedef void ExtDexFileMethodInfoCallback(const struct ExtDexFileMethodInfo* ext_method_info, + void* user_data); + +// See art_api::dex::DexFile::GetAllMethodInfos. +void ExtDexFileGetAllMethodInfos(struct ExtDexFile* ext_dex_file, + int with_signature, + ExtDexFileMethodInfoCallback* method_info_cb, + void* user_data); + +// Frees an ExtDexFile. +void ExtDexFileFree(struct ExtDexFile* ext_dex_file); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_EXTERNAL_H_ diff --git a/libdexfile/external/include/art_api/dex_file_support.h b/libdexfile/external/include/art_api/dex_file_support.h index 99d60d1cd8..9a20a30c4b 100644 --- a/libdexfile/external/include/art_api/dex_file_support.h +++ b/libdexfile/external/include/art_api/dex_file_support.h @@ -17,9 +17,7 @@ #ifndef ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_SUPPORT_H_ #define ART_LIBDEXFILE_EXTERNAL_INCLUDE_ART_API_DEX_FILE_SUPPORT_H_ -// Dex file external API - -#include <sys/types.h> +// C++ wrapper for the dex file external API. #include <cstring> #include <memory> @@ -29,69 +27,7 @@ #include <android-base/macros.h> -extern "C" { - -// This is the stable C ABI that backs art_api::dex below. Structs and functions -// may only be added here. -// TODO(b/120978655): Move this to a separate pure C header. -// -// Clients should use the C++ wrappers in art_api::dex instead. - -// Opaque wrapper for an std::string allocated in libdexfile which must be freed -// using ExtDexFileFreeString. -class ExtDexFileString; - -// Returns an ExtDexFileString initialized to the given string. -const ExtDexFileString* ExtDexFileMakeString(const char* str); - -// Returns a pointer to the underlying null-terminated character array and its -// size for the given ExtDexFileString. -const char* ExtDexFileGetString(const ExtDexFileString* ext_string, /*out*/ size_t* size); - -// Frees an ExtDexFileString. -void ExtDexFileFreeString(const ExtDexFileString* ext_string); - -struct ExtDexFileMethodInfo { - int32_t offset; - int32_t len; - const ExtDexFileString* name; -}; - -class ExtDexFile; - -// See art_api::dex::DexFile::OpenFromMemory. Returns true on success. -int ExtDexFileOpenFromMemory(const void* addr, - /*inout*/ size_t* size, - const char* location, - /*out*/ const ExtDexFileString** error_msg, - /*out*/ ExtDexFile** ext_dex_file); - -// See art_api::dex::DexFile::OpenFromFd. Returns true on success. -int ExtDexFileOpenFromFd(int fd, - off_t offset, - const char* location, - /*out*/ const ExtDexFileString** error_msg, - /*out*/ ExtDexFile** ext_dex_file); - -// See art_api::dex::DexFile::GetMethodInfoForOffset. Returns true on success. -int ExtDexFileGetMethodInfoForOffset(ExtDexFile* ext_dex_file, - int64_t dex_offset, - int with_signature, - /*out*/ ExtDexFileMethodInfo* method_info); - -typedef void ExtDexFileMethodInfoCallback(const ExtDexFileMethodInfo* ext_method_info, - void* user_data); - -// See art_api::dex::DexFile::GetAllMethodInfos. -void ExtDexFileGetAllMethodInfos(ExtDexFile* ext_dex_file, - int with_signature, - ExtDexFileMethodInfoCallback* method_info_cb, - void* user_data); - -// Frees an ExtDexFile. -void ExtDexFileFree(ExtDexFile* ext_dex_file); - -} // extern "C" +#include "art_api/dex_file_external.h" namespace art_api { namespace dex { |