summaryrefslogtreecommitdiffstats
path: root/scripts/relocate_sdk.py
diff options
context:
space:
mode:
authorLaurentiu Palcu <laurentiu.palcu@intel.com>2012-07-31 11:49:35 +0300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-08-02 15:28:38 +0100
commit749b8a52c68500cca546d705b7ac81905c1fe0e7 (patch)
tree76502782380ca380b803459c89b8adf0fe76efb2 /scripts/relocate_sdk.py
parent77973e3004b9d3e2d5a59715e30d46e9351d0008 (diff)
downloadpoky-749b8a52c68500cca546d705b7ac81905c1fe0e7.tar.gz
scripts: add script for relocating the SDK
This script will be embedded in the SDK tarball and will be called by the SDK installer. It replaces the interpreter path in all binaries and it also changes the ld.so.cache and SYSDIRS in dynamic loader. (From OE-Core rev: 3d366f4953962566f33a3d77d65ed0bd2c48f922) Signed-off-by: Laurentiu Palcu <laurentiu.palcu@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/relocate_sdk.py')
-rwxr-xr-xscripts/relocate_sdk.py200
1 files changed, 200 insertions, 0 deletions
diff --git a/scripts/relocate_sdk.py b/scripts/relocate_sdk.py
new file mode 100755
index 0000000000..b247e65ce3
--- /dev/null
+++ b/scripts/relocate_sdk.py
@@ -0,0 +1,200 @@
1#!/usr/bin/env python
2#
3# Copyright (c) 2012 Intel Corporation
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17#
18# DESCRIPTION
19# This script is called by the SDK installer script. It replaces the dynamic
20# loader path in all binaries and also fixes the SYSDIR paths/lengths and the
21# location of ld.so.cache in the dynamic loader binary
22#
23# AUTHORS
24# Laurentiu Palcu <laurentiu.palcu@intel.com>
25#
26
27import struct
28import sys
29import stat
30import os
31import re
32
33old_prefix = re.compile("##DEFAULT_INSTALL_DIR##")
34
35def get_arch():
36 f.seek(0)
37 e_ident =f.read(16)
38 ei_mag0,ei_mag1_3,ei_class = struct.unpack("<B3sB11x", e_ident)
39
40 if (ei_mag0 != 0x7f and ei_mag1_3 != "ELF") or ei_class == 0:
41 return 0
42
43 if ei_class == 1:
44 return 32
45 elif ei_class == 2:
46 return 64
47
48def parse_elf_header():
49 global e_type, e_machine, e_version, e_entry, e_phoff, e_shoff, e_flags,\
50 e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx
51
52 f.seek(0)
53 elf_header = f.read(64)
54
55 if arch == 32:
56 # 32bit
57 hdr_struct = struct.Struct("<HHILLLIHHHHHH")
58 hdr_size = 52
59 else:
60 # 64bit
61 hdr_struct = struct.Struct("<HHIQQQIHHHHHH")
62 hdr_size = 64
63
64 e_type, e_machine, e_version, e_entry, e_phoff, e_shoff, e_flags,\
65 e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx =\
66 hdr_struct.unpack(elf_header[16:hdr_size])
67
68def change_interpreter():
69 if arch == 32:
70 ph_struct = struct.Struct("<IIIIIIII")
71 else:
72 ph_struct = struct.Struct("<IIQQQQQQ")
73
74 """ look for PT_INTERP section """
75 for i in range(0,e_phnum):
76 f.seek(e_phoff + i * e_phentsize)
77 ph_hdr = f.read(e_phentsize)
78 if arch == 32:
79 # 32bit
80 p_type, p_offset, p_vaddr, p_paddr, p_filesz,\
81 p_memsz, p_flags, p_align = ph_struct.unpack(ph_hdr)
82 else:
83 # 64bit
84 p_type, p_flags, p_offset, p_vaddr, p_paddr, \
85 p_filesz, p_memsz, p_align = ph_struct.unpack(ph_hdr)
86
87 """ change interpreter """
88 if p_type == 3:
89 # PT_INTERP section
90 f.seek(p_offset)
91 dl_path = new_dl_path + "\0" * (e_phentsize - len(new_dl_path))
92 f.write(new_dl_path)
93 break
94
95def change_dl_sysdirs():
96 if arch == 32:
97 sh_struct = struct.Struct("<IIIIIIIIII")
98 else:
99 sh_struct = struct.Struct("<IIQQQQIIQQ")
100
101 """ read section string table """
102 f.seek(e_shoff + e_shstrndx * e_shentsize)
103 sh_hdr = f.read(e_shentsize)
104 if arch == 32:
105 sh_offset, sh_size = struct.unpack("<16xII16x", sh_hdr)
106 else:
107 sh_offset, sh_size = struct.unpack("<24xQQ24x", sh_hdr)
108
109 f.seek(sh_offset)
110 sh_strtab = f.read(sh_size)
111
112 sysdirs = sysdirs_len = ""
113
114 """ change ld.so.cache path and default libs path for dynamic loader """
115 for i in range(0,e_shnum):
116 f.seek(e_shoff + i * e_shentsize)
117 sh_hdr = f.read(e_shentsize)
118
119 sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link,\
120 sh_info, sh_addralign, sh_entsize = sh_struct.unpack(sh_hdr)
121
122 name = sh_strtab[sh_name:sh_strtab.find("\0", sh_name)]
123
124 """ look only into SHT_PROGBITS sections """
125 if sh_type == 1:
126 f.seek(sh_offset)
127 """ default library paths cannot be changed on the fly because """
128 """ the string lengths have to be changed too. """
129 if name == ".sysdirs":
130 sysdirs = f.read(sh_size)
131 sysdirs_off = sh_offset
132 sysdirs_sect_size = sh_size
133 elif name == ".sysdirslen":
134 sysdirslen = f.read(sh_size)
135 sysdirslen_off = sh_offset
136 elif name == ".ldsocache":
137 ldsocache_path = f.read(sh_size)
138 new_ldsocache_path = old_prefix.sub(new_prefix, ldsocache_path)
139 # pad with zeros
140 new_ldsocache_path += "\0" * (sh_size - len(new_ldsocache_path))
141 # write it back
142 f.seek(sh_offset)
143 f.write(new_ldsocache_path)
144
145 if sysdirs != "" and sysdirslen != "":
146 paths = sysdirs.split("\0")
147 sysdirs = ""
148 sysdirslen = ""
149 for path in paths:
150 """ exit the loop when we encounter first empty string """
151 if path == "":
152 break
153
154 new_path = old_prefix.sub(new_prefix, path)
155 sysdirs += new_path + "\0"
156
157 if arch == 32:
158 sysdirslen += struct.pack("<L", len(new_path))
159 else:
160 sysdirslen += struct.pack("<Q", len(new_path))
161
162 """ pad with zeros """
163 sysdirs += "\0" * (sysdirs_sect_size - len(sysdirs))
164
165 """ write the sections back """
166 f.seek(sysdirs_off)
167 f.write(sysdirs)
168 f.seek(sysdirslen_off)
169 f.write(sysdirslen)
170
171
172# MAIN
173if len(sys.argv) < 4:
174 exit(1)
175
176new_prefix = sys.argv[1]
177new_dl_path = sys.argv[2]
178executables_list = sys.argv[3:]
179
180for e in executables_list:
181 perms = os.stat(e)[stat.ST_MODE]
182 if os.access(e, os.W_OK|os.R_OK):
183 perms = None
184 else:
185 os.chmod(e, perms|stat.S_IRWXU)
186
187 f = open(e, "r+b")
188
189 arch = get_arch()
190 if arch:
191 parse_elf_header()
192 change_interpreter()
193 change_dl_sysdirs()
194
195 """ change permissions back """
196 if perms:
197 os.chmod(e, perms)
198
199 f.close()
200