2012-06-19 11:21:29 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2012 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.
|
|
|
|
*/
|
|
|
|
#ifndef LINKER_PHDR_H
|
|
|
|
#define LINKER_PHDR_H
|
|
|
|
|
|
|
|
/* Declarations related to the ELF program header table and segments.
|
|
|
|
*
|
|
|
|
* The design goal is to provide an API that is as close as possible
|
|
|
|
* to the ELF spec, and does not depend on linker-specific data
|
|
|
|
* structures (e.g. the exact layout of struct soinfo).
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "linker.h"
|
|
|
|
|
2013-03-06 03:47:58 +01:00
|
|
|
class ElfReader {
|
|
|
|
public:
|
|
|
|
ElfReader(const char* name, int fd);
|
|
|
|
~ElfReader();
|
2012-06-19 11:21:29 +02:00
|
|
|
|
2013-03-06 03:47:58 +01:00
|
|
|
bool Load();
|
2012-06-19 11:21:29 +02:00
|
|
|
|
2013-03-06 03:47:58 +01:00
|
|
|
size_t phdr_count() { return phdr_num_; }
|
|
|
|
Elf32_Addr load_start() { return reinterpret_cast<Elf32_Addr>(load_start_); }
|
|
|
|
Elf32_Addr load_size() { return load_size_; }
|
|
|
|
Elf32_Addr load_bias() { return load_bias_; }
|
|
|
|
const Elf32_Phdr* loaded_phdr() { return loaded_phdr_; }
|
2012-06-19 11:21:29 +02:00
|
|
|
|
2013-03-06 03:47:58 +01:00
|
|
|
private:
|
|
|
|
bool ReadElfHeader();
|
|
|
|
bool VerifyElfHeader();
|
|
|
|
bool ReadProgramHeader();
|
|
|
|
bool ReserveAddressSpace();
|
|
|
|
bool LoadSegments();
|
|
|
|
bool FindPhdr();
|
|
|
|
bool CheckPhdr(Elf32_Addr);
|
2012-06-19 11:21:29 +02:00
|
|
|
|
2013-03-06 03:47:58 +01:00
|
|
|
const char* name_;
|
|
|
|
int fd_;
|
|
|
|
|
|
|
|
Elf32_Ehdr header_;
|
|
|
|
size_t phdr_num_;
|
|
|
|
|
|
|
|
void* phdr_mmap_;
|
|
|
|
Elf32_Phdr* phdr_table_;
|
|
|
|
Elf32_Addr phdr_size_;
|
|
|
|
|
|
|
|
// First page of reserved address space.
|
|
|
|
void* load_start_;
|
|
|
|
// Size in bytes of reserved address space.
|
|
|
|
Elf32_Addr load_size_;
|
|
|
|
// Load bias.
|
|
|
|
Elf32_Addr load_bias_;
|
|
|
|
|
|
|
|
// Loaded phdr.
|
|
|
|
const Elf32_Phdr* loaded_phdr_;
|
|
|
|
};
|
|
|
|
|
|
|
|
Elf32_Addr phdr_table_get_load_size(const Elf32_Phdr* phdr, size_t phnum);
|
2012-06-19 11:21:29 +02:00
|
|
|
|
|
|
|
int
|
|
|
|
phdr_table_protect_segments(const Elf32_Phdr* phdr_table,
|
|
|
|
int phdr_count,
|
|
|
|
Elf32_Addr load_bias);
|
|
|
|
|
|
|
|
int
|
|
|
|
phdr_table_unprotect_segments(const Elf32_Phdr* phdr_table,
|
|
|
|
int phdr_count,
|
|
|
|
Elf32_Addr load_bias);
|
|
|
|
|
|
|
|
int
|
|
|
|
phdr_table_protect_gnu_relro(const Elf32_Phdr* phdr_table,
|
|
|
|
int phdr_count,
|
|
|
|
Elf32_Addr load_bias);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef ANDROID_ARM_LINKER
|
|
|
|
int
|
|
|
|
phdr_table_get_arm_exidx(const Elf32_Phdr* phdr_table,
|
|
|
|
int phdr_count,
|
|
|
|
Elf32_Addr load_bias,
|
|
|
|
Elf32_Addr** arm_exidx,
|
|
|
|
unsigned* arm_exidix_count);
|
|
|
|
#endif
|
|
|
|
|
linker: avoid clobbering the .dynamic section of shared libs
This patch removes the DT_NEEDED hack which stores pointers
to soinfo structs in the .dynamic section of the library
being loaded.
Instead, it caches the soinfo struct pointers on the stack
during relocation time. After relocation time, i.e. when
calling constructors and destructors of the shared library
and its dependencies, uncached access is used instead,
doing lookups using the string table entries pointed to by
the DT_NEEDED entries.
By removing this hack, it is no longer needed to undo the
PT_GNURELRO protection, i.e., all non-writable mappings
can remain non-writable during their entire lifespan.
Even though, strictly speaking, the algorithmic complexity
has increased somewhat, the real-world adverse effect
is negligible on the systems I have tested.
Change-Id: I2361502560b96b5878f7f94a8e8a215350d70d64
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@gmail.com>
2012-08-14 12:30:09 +02:00
|
|
|
void
|
2012-06-19 11:21:29 +02:00
|
|
|
phdr_table_get_dynamic_section(const Elf32_Phdr* phdr_table,
|
|
|
|
int phdr_count,
|
linker: avoid clobbering the .dynamic section of shared libs
This patch removes the DT_NEEDED hack which stores pointers
to soinfo structs in the .dynamic section of the library
being loaded.
Instead, it caches the soinfo struct pointers on the stack
during relocation time. After relocation time, i.e. when
calling constructors and destructors of the shared library
and its dependencies, uncached access is used instead,
doing lookups using the string table entries pointed to by
the DT_NEEDED entries.
By removing this hack, it is no longer needed to undo the
PT_GNURELRO protection, i.e., all non-writable mappings
can remain non-writable during their entire lifespan.
Even though, strictly speaking, the algorithmic complexity
has increased somewhat, the real-world adverse effect
is negligible on the systems I have tested.
Change-Id: I2361502560b96b5878f7f94a8e8a215350d70d64
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@gmail.com>
2012-08-14 12:30:09 +02:00
|
|
|
Elf32_Addr load_bias,
|
2013-03-01 00:58:45 +01:00
|
|
|
Elf32_Dyn** dynamic,
|
2013-01-12 00:32:20 +01:00
|
|
|
size_t* dynamic_count,
|
|
|
|
Elf32_Word* dynamic_flags);
|
2012-06-19 11:21:29 +02:00
|
|
|
|
|
|
|
#endif /* LINKER_PHDR_H */
|