Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(709)

Side by Side Diff: third_party/android_crazy_linker/src/src/crazy_linker_elf_view.cpp

Issue 1180693002: Update from https://crrev.com/333737 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "crazy_linker_elf_view.h"
6
7 #include <errno.h>
8
9 #include "crazy_linker_debug.h"
10 #include "crazy_linker_error.h"
11 #include "linker_phdr.h"
12
13 namespace crazy {
14
15 bool ElfView::InitUnmapped(ELF::Addr load_address,
16 const ELF::Phdr* phdr,
17 size_t phdr_count,
18 Error* error) {
19 // Compute load size and bias.
20 ELF::Addr min_vaddr = 0;
21 load_size_ = phdr_table_get_load_size(phdr, phdr_count, &min_vaddr, NULL);
22 if (load_size_ == 0) {
23 *error = "Invalid program header table";
24 return false;
25 }
26 load_address_ = (load_address ? load_address : min_vaddr);
27 load_bias_ = load_address - min_vaddr;
28
29 // Extract the dynamic table information.
30 phdr_table_get_dynamic_section(phdr,
31 phdr_count,
32 load_bias_,
33 &dynamic_,
34 &dynamic_count_,
35 &dynamic_flags_);
36 if (!dynamic_) {
37 *error = "No PT_DYNAMIC section!";
38 return false;
39 }
40
41 // Compute the program header table address relative to load_address.
42 // This is different from |phdr|..|phdr + phdr_count| which can actually
43 // be at a different location.
44 const ELF::Phdr* phdr0 = NULL;
45
46 // First, if there is a PT_PHDR, use it directly.
47 for (size_t n = 0; n < phdr_count; ++n) {
48 const ELF::Phdr* entry = &phdr[n];
49 if (entry->p_type == PT_PHDR) {
50 phdr0 = entry;
51 break;
52 }
53 }
54
55 // Otherwise, check the first loadable segment. If its file offset
56 // is 0, it starts with the ELF header, and we can trivially find the
57 // loaded program header from it.
58 if (!phdr0) {
59 for (size_t n = 0; n < phdr_count; ++n) {
60 const ELF::Phdr* entry = &phdr[n];
61 if (entry->p_type == PT_LOAD) {
62 if (entry->p_offset == 0) {
63 ELF::Addr elf_addr = load_bias_ + entry->p_vaddr;
64 const ELF::Ehdr* ehdr = reinterpret_cast<const ELF::Ehdr*>(elf_addr);
65 ELF::Addr offset = ehdr->e_phoff;
66 phdr0 = reinterpret_cast<const ELF::Phdr*>(elf_addr + offset);
67 }
68 break;
69 }
70 }
71 }
72
73 // Check that the program header table is indeed in a loadable segment,
74 // this helps catching malformed ELF binaries.
75 if (phdr0) {
76 ELF::Addr phdr0_addr = reinterpret_cast<ELF::Addr>(phdr0);
77 ELF::Addr phdr0_limit = phdr0_addr + sizeof(ELF::Phdr) * phdr_count;
78 bool found = false;
79 for (size_t n = 0; n < phdr_count; ++n) {
80 size_t seg_start = load_bias_ + phdr[n].p_vaddr;
81 size_t seg_end = seg_start + phdr[n].p_filesz;
82
83 if (seg_start <= phdr0_addr && phdr0_limit <= seg_end) {
84 found = true;
85 break;
86 }
87 }
88
89 if (!found)
90 phdr0 = NULL;
91 }
92
93 if (!phdr0) {
94 *error = "Malformed ELF binary";
95 return false;
96 }
97
98 phdr_ = phdr0;
99 phdr_count_ = phdr_count;
100
101 LOG("%s: New ELF view [load_address:%p, load_size:%p, load_bias:%p, phdr:%p, "
102 "phdr_count:%d, dynamic:%p, dynamic_count:%d, dynamic_flags:%d\n",
103 __FUNCTION__,
104 load_address_,
105 load_size_,
106 load_bias_,
107 phdr_,
108 phdr_count_,
109 dynamic_,
110 dynamic_count_,
111 dynamic_flags_);
112 return true;
113 }
114
115 bool ElfView::ProtectRelroSection(Error* error) {
116 LOG("%s: Enabling GNU RELRO protection\n", __FUNCTION__);
117
118 if (phdr_table_protect_gnu_relro(phdr_, phdr_count_, load_bias_) < 0) {
119 error->Format("Can't enable GNU RELRO protection: %s", strerror(errno));
120 return false;
121 }
122 return true;
123 }
124
125 } // namespace crazy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698