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
This commit is contained in:
parent
5b9cc31442
commit
6663f5525d
7 changed files with 108 additions and 16 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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"],
|
||||
}
|
||||
|
|
31
tests/libs/relr.cpp
Normal file
31
tests/libs/relr.cpp
Normal file
|
@ -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";
|
||||
}
|
Loading…
Reference in a new issue