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

Side by Side Diff: tools/relocation_packer/src/relocation_packer_elf_file.h

Issue 310483003: Add a host tool to pack R_ARM_RELATIVE relocations in libchrome.<ver>.so. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 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 // ELF shared object file updates handler.
6 //
7 // Provides functions to remove R_ARM_RELATIVE relocations from the .rel.dyn
8 // section and pack them in .android.rel.dyn, and unpack to return the file
9 // to its pre-packed state.
10 //
11 // Files to be packed or unpacked must include an existing .android.rel.dyn
12 // section. A standard libchrome.<version>.so will not contain this section,
13 // so the following can be used to add one:
14 //
15 // echo -n 'NULL' >/tmp/small
16 // arm-linux-gnueabi-objcopy
17 // --add-section .android.rel.dyn=/tmp/small
18 // libchrome.<version>.so libchrome.<version>.so.packed
19 // rm /tmp/small
20 //
21 // To use, open the file and pass the file descriptor to the Load() function,
22 // pack or unpack as desired, and then call Flush(). Example:
23 //
24 // int fd = open(..., O_RDWR);
25 //
26 // ElfFile elf_file;
27 // if (!elf_file.Load(fd))
28 // abort();
29 //
30 // bool status;
31 // if (is_packing)
32 // status = elf_file.PackRelocations();
33 // else
34 // status = elf_file.UnpackRelocations();
35 //
36 // if (status)
37 // elf_file.Flush();
38 //
39 // SetPadding() causes PackRelocations() to pad .rel.dyn with R_ARM_NONE
40 // entries rather than cutting a hole out of the shared object file. This
41 // keeps all load addresses and offsets constant, and enables easier
42 // debugging and testing.
43 //
44 // A packed shared object file has all of its R_ARM_RELATIVE relocations
45 // removed from .rel.dyn, and replaced as packed data in .android.rel.dyn.
46 // The resulting file is shorter than its non-packed original.
47 //
48 // Unpacking a packed file restores the file to its non-packed state, by
49 // expanding the packed data in android.rel.dyn, combining the R_ARM_RELATIVE
50 // relocations with the data already in .rel.dyn, and then writing back the
51 // now expanded .rel.dyn section.
52
53 #ifndef RELOCATION_PACKER_ELF_FILE_H
54 #define RELOCATION_PACKER_ELF_FILE_H
55
56 #include <string.h>
57
58 #include "elf.h"
59 #include "libelf.h"
60 #include "relocation_packer_packer.h"
61
62 namespace relocation_packer {
63
64 // An ElfFile reads shared objects, and shuttles R_ARM_RELATIVE relocations
65 // between .rel.dyn and .android.rel.dyn sections.
66 class ElfFile {
rmcilroy 2014/06/02 15:16:35 How about "class ArmElfFile : public ElfFile" (wit
simonb (inactive) 2014/06/04 16:40:35 There's no current plan to port to other architect
rmcilroy 2014/06/07 11:49:06 Arm64 is a different architecture. I'm fine with
67 public:
68 // Stub identifier written to 'null out' packed data, "NULL".
69 static const Elf32_Word kStubIdentifier = 0x4c4c554eu;
70
71 // Additional dynamic tags used to indicate the offset and size of the
72 // .android.rel.dyn section.
73 static const Elf32_Sword DT_ANDROID_ARM_REL_OFFSET = DT_LOPROC;
74 static const Elf32_Sword DT_ANDROID_ARM_REL_SIZE = DT_LOPROC + 1;
rmcilroy 2014/06/02 15:16:35 Do these (and kStubIdentifier above) need to be in
simonb (inactive) 2014/06/04 16:40:35 Done.
75
76 ElfFile() { ::memset(this, 0, sizeof(*this)); }
77 ~ElfFile() {}
78
79 // Load a new ElfFile from a filedescriptor. If flushing, the file must
80 // be open for read/write.
81 // |fd| is an open file descriptor for the shared object.
82 bool Load(int fd);
rmcilroy 2014/06/02 15:16:35 nit - mention what is returned on success or failu
simonb (inactive) 2014/06/04 16:40:35 Done.
83
84 // Set padding mode. When padding, PackRelocations() will not shrink
85 // the .rel.dyn section, but instead replace R_ARM_RELATIVE with
86 // R_ARM_NONE entries.
87 // |flag| is true to pad .rel.dyn, false to shrink it.
88 inline void SetPadding(bool flag) { is_padding_rel_dyn_ = flag; }
89
90 // Transfer R_ARM_RELATIVE relocations from .rel.dyn to a packed
91 // representation in .android.rel.dyn.
92 bool PackRelocations();
93
94 // Transfer R_ARM_RELATIVE relocations from a packed representation in
95 // .android.rel.dyn to .rel.dyn.
96 bool UnpackRelocations();
97
98 // Write ELF file changes.
99 void Flush();
rmcilroy 2014/06/02 15:16:35 Is there a reason to have Load and Flush as separa
simonb (inactive) 2014/06/04 16:40:35 Done.
100
101 private:
102 // If set, pad rather than shrink .rel.dyn. Primarily for debugging,
103 // allows packing to be checked without affecting load addresses.
104 bool is_padding_rel_dyn_;
105
106 // File descriptor opened on the shared object.
107 int fd_;
108
109 // Libelf handle, assigned by Load().
110 Elf* elf_;
111
112 // Sections that we manipulate, assigned by Load().
113 Elf_Scn* rel_dyn_section_;
114 Elf_Scn* dynamic_section_;
115 Elf_Scn* android_rel_dyn_section_;
116 };
117
118 } // namespace relocation_packer
119
120 #endif // RELOCATION_PACKER_ELF_FILE_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698