diff options
author | Elliott Hughes <enh@google.com> | 2020-01-24 14:36:10 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2020-01-24 15:39:01 -0800 |
commit | 6663f5525dafc31de1891d7e0fa6da88c4c7dc4b (patch) | |
tree | 20be89b877823e6c2c3521037aa4a21f6bcb0345 | |
parent | 5b9cc3144239511ec9062a3ff47dc20202848388 (diff) |
Modernize SHT_RELR support.
Until now we've only supported RELR with our own OS-private-use
constants. Add support for the official numbers (while maintaining
support for the historical numbers).
Add tests to ensure we continue to support both indefinitely.
We can't yet flip the build system over to using the official constants
because the old GNU binutils objcopy we still use in most cases (for the
mini-debug section) only supports the historical constants.
Bug: http://b/147452927
Test: treehugger
Change-Id: If214fce7fade4316115947e90b78ab40864b61f2
-rw-r--r-- | android-changes-for-ndk-developers.md | 16 | ||||
-rw-r--r-- | libc/include/elf.h | 33 | ||||
-rw-r--r-- | linker/linker.cpp | 6 | ||||
-rw-r--r-- | tests/Android.bp | 2 | ||||
-rw-r--r-- | tests/dlfcn_test.cpp | 10 | ||||
-rw-r--r-- | tests/libs/Android.bp | 26 | ||||
-rw-r--r-- | tests/libs/relr.cpp | 31 |
7 files changed, 108 insertions, 16 deletions
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md index 84456f988..a0f3c3c50 100644 --- a/android-changes-for-ndk-developers.md +++ b/android-changes-for-ndk-developers.md @@ -456,3 +456,19 @@ Most apps should be unaffected by this change, but apps that hook or try to detect hooking of C library functions might need to fix their code to cope with IFUNC relocations. The affected functions are from `<string.h>`, but may expand to include more functions (and more libraries) in future. + +## Relative relocations (RELR) + +Android added experimental support for RELR relative relocations +in API level 28, but using `SHT_` and `DT_` constants in the space +reserved for OS private use. + +API level 30 added support for ELF files using the official `SHT_` and +`DT_` constants. + +The RELR encoding is unrelated to the earlier "packed relocations" +format available from API level 23. + +There are no plans to remove support for ELF files using the older +OS private use constants for RELR, nor for ELF files using packed +relocations. diff --git a/libc/include/elf.h b/libc/include/elf.h index f5b209193..bebaea127 100644 --- a/libc/include/elf.h +++ b/libc/include/elf.h @@ -26,8 +26,7 @@ * SUCH DAMAGE. */ -#ifndef _ELF_H -#define _ELF_H +#pragma once #include <sys/cdefs.h> @@ -245,13 +244,9 @@ typedef Elf64_Xword Elf64_Relr; /* glibc and BSD disagree for DT_ENCODING; glibc looks wrong. */ #define DT_PREINIT_ARRAY 32 #define DT_PREINIT_ARRAYSZ 33 - -/* Experimental support for SHT_RELR sections. For details, see proposal - at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg */ -#define DT_RELR 0x6fffe000 -#define DT_RELRSZ 0x6fffe001 -#define DT_RELRENT 0x6fffe003 -#define DT_RELRCOUNT 0x6fffe005 +#define DT_RELRSZ 35 +#define DT_RELR 36 +#define DT_RELRENT 37 /* Android compressed rel/rela sections */ #define DT_ANDROID_REL (DT_LOOS + 2) @@ -502,15 +497,12 @@ typedef Elf64_Xword Elf64_Relr; #define SHT_PREINIT_ARRAY 16 #define SHT_GROUP 17 #define SHT_SYMTAB_SHNDX 18 +#define SHT_RELR 19 #undef SHT_NUM -#define SHT_NUM 19 +#define SHT_NUM 20 #define SHT_LOOS 0x60000000 #define SHT_HIOS 0x6fffffff -/* Experimental support for SHT_RELR sections. For details, see proposal - at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg */ -#define SHT_RELR 0x6fffff00 - /* http://www.sco.com/developers/gabi/latest/ch4.symtab.html */ #define STN_UNDEF 0 @@ -540,4 +532,15 @@ typedef Elf64_Xword Elf64_Relr; #define VER_NDX_LOCAL 0 #define VER_NDX_GLOBAL 1 -#endif /* _ELF_H */ +/* + * Experimental support for SHT_RELR sections. For details, see proposal + * at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg. + * This was eventually replaced by SHT_RELR and DT_RELR (which are identical + * other than their different constants), but those constants are only + * supported by the OS starting at API level 30. + */ +#define SHT_ANDROID_RELR 0x6fffff00 +#define DT_ANDROID_RELR 0x6fffe000 +#define DT_ANDROID_RELRSZ 0x6fffe001 +#define DT_ANDROID_RELRENT 0x6fffe003 +#define DT_ANDROID_RELRCOUNT 0x6fffe005 diff --git a/linker/linker.cpp b/linker/linker.cpp index 57554fb92..8de82d543 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -3070,14 +3070,17 @@ bool soinfo::prelink_image() { #endif case DT_RELR: + case DT_ANDROID_RELR: relr_ = reinterpret_cast<ElfW(Relr)*>(load_bias + d->d_un.d_ptr); break; case DT_RELRSZ: + case DT_ANDROID_RELRSZ: relr_count_ = d->d_un.d_val / sizeof(ElfW(Relr)); break; case DT_RELRENT: + case DT_ANDROID_RELRENT: if (d->d_un.d_val != sizeof(ElfW(Relr))) { DL_ERR("invalid DT_RELRENT: %zd", static_cast<size_t>(d->d_un.d_val)); return false; @@ -3085,7 +3088,8 @@ bool soinfo::prelink_image() { break; // Ignored (see DT_RELCOUNT comments for details). - case DT_RELRCOUNT: + // There is no DT_RELRCOUNT specifically because it would only be ignored. + case DT_ANDROID_RELRCOUNT: break; case DT_INIT: diff --git a/tests/Android.bp b/tests/Android.bp index d3769db14..2bfe42bed 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -613,6 +613,8 @@ cc_defaults { "libdl_preempt_test_2", "libdl_test_df_1_global", "libgnu-hash-table-library", + "librelr-new", + "librelr-old", "libsysv-hash-table-library", "libtestshared", "libtest_atexit", diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp index d815dba5e..e36883af1 100644 --- a/tests/dlfcn_test.cpp +++ b/tests/dlfcn_test.cpp @@ -1765,3 +1765,13 @@ TEST(dlfcn, segment_gap) { } #endif + +TEST(dlfcn, relr_old) { + void* handle = dlopen("librelr-old.so", RTLD_NOW); + ASSERT_TRUE(handle != nullptr) << dlerror(); +} + +TEST(dlfcn, relr_new) { + void* handle = dlopen("librelr-new.so", RTLD_NOW); + ASSERT_TRUE(handle != nullptr) << dlerror(); +} diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp index 2ee6c8665..29224f541 100644 --- a/tests/libs/Android.bp +++ b/tests/libs/Android.bp @@ -1497,3 +1497,29 @@ cc_test_library { defaults: ["bionic_testlib_defaults"], srcs: ["segment_gap_inner.cpp"], } + + +// ----------------------------------------------------------------------------- +// Check that we support both the old and new SHT_RELR constants. +// ----------------------------------------------------------------------------- + +cc_test_library { + name: "librelr-new", + ldflags: ["-Wl,--no-use-android-relr-tags"], + host_supported: false, + defaults: ["bionic_testlib_defaults"], + srcs: ["relr.cpp"], + // Hack to ensure we're using llvm-objcopy because our binutils prebuilt + // only supports the old numbers (http://b/141010852). + strip: { + keep_symbols: true, + }, +} + +cc_test_library { + name: "librelr-old", + ldflags: ["-Wl,--use-android-relr-tags"], + host_supported: false, + defaults: ["bionic_testlib_defaults"], + srcs: ["relr.cpp"], +} diff --git a/tests/libs/relr.cpp b/tests/libs/relr.cpp new file mode 100644 index 000000000..7ea07b52d --- /dev/null +++ b/tests/libs/relr.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +extern "C" const char* relr() { + return "relr"; +} |