diff options
Diffstat (limited to 'scripts/relocate_sdk.py')
| -rwxr-xr-x | scripts/relocate_sdk.py | 67 | 
1 files changed, 55 insertions, 12 deletions
| diff --git a/scripts/relocate_sdk.py b/scripts/relocate_sdk.py index 8c0fdb986a..9e01c09cb0 100755 --- a/scripts/relocate_sdk.py +++ b/scripts/relocate_sdk.py | |||
| @@ -30,9 +30,16 @@ else: | |||
| 30 | old_prefix = re.compile(b("##DEFAULT_INSTALL_DIR##")) | 30 | old_prefix = re.compile(b("##DEFAULT_INSTALL_DIR##")) | 
| 31 | 31 | ||
| 32 | def get_arch(): | 32 | def get_arch(): | 
| 33 | global endian_prefix | ||
| 33 | f.seek(0) | 34 | f.seek(0) | 
| 34 | e_ident =f.read(16) | 35 | e_ident =f.read(16) | 
| 35 | ei_mag0,ei_mag1_3,ei_class = struct.unpack("<B3sB11x", e_ident) | 36 | ei_mag0,ei_mag1_3,ei_class,ei_data,ei_version = struct.unpack("<B3sBBB9x", e_ident) | 
| 37 | |||
| 38 | # ei_data = 1 for little-endian & 0 for big-endian | ||
| 39 | if ei_data == 1: | ||
| 40 | endian_prefix = '<' | ||
| 41 | else: | ||
| 42 | endian_prefix = '>' | ||
| 36 | 43 | ||
| 37 | if (ei_mag0 != 0x7f and ei_mag1_3 != "ELF") or ei_class == 0: | 44 | if (ei_mag0 != 0x7f and ei_mag1_3 != "ELF") or ei_class == 0: | 
| 38 | return 0 | 45 | return 0 | 
| @@ -42,6 +49,34 @@ def get_arch(): | |||
| 42 | elif ei_class == 2: | 49 | elif ei_class == 2: | 
| 43 | return 64 | 50 | return 64 | 
| 44 | 51 | ||
| 52 | def get_dl_arch(dl_path): | ||
| 53 | try: | ||
| 54 | with open(dl_path, "r+b") as f: | ||
| 55 | e_ident =f.read(16) | ||
| 56 | except IOError: | ||
| 57 | exctype, ioex = sys.exc_info()[:2] | ||
| 58 | if ioex.errno == errno.ETXTBSY: | ||
| 59 | print("Could not open %s. File used by another process.\nPlease "\ | ||
| 60 | "make sure you exit all processes that might use any SDK "\ | ||
| 61 | "binaries." % e) | ||
| 62 | else: | ||
| 63 | print("Could not open %s: %s(%d)" % (e, ioex.strerror, ioex.errno)) | ||
| 64 | sys.exit(-1) | ||
| 65 | |||
| 66 | ei_mag0,ei_mag1_3,ei_class,ei_data,ei_version = struct.unpack("<B3sBBB9x", e_ident) | ||
| 67 | |||
| 68 | if (ei_mag0 != 0x7f and ei_mag1_3 != "ELF") or ei_class == 0: | ||
| 69 | print("ERROR: unknow %s" % dl_path) | ||
| 70 | sys.exit(-1) | ||
| 71 | |||
| 72 | if ei_class == 1: | ||
| 73 | arch = 32 | ||
| 74 | elif ei_class == 2: | ||
| 75 | arch = 64 | ||
| 76 | |||
| 77 | return arch | ||
| 78 | |||
| 79 | |||
| 45 | def parse_elf_header(): | 80 | def parse_elf_header(): | 
| 46 | global e_type, e_machine, e_version, e_entry, e_phoff, e_shoff, e_flags,\ | 81 | global e_type, e_machine, e_version, e_entry, e_phoff, e_shoff, e_flags,\ | 
| 47 | e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx | 82 | e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx | 
| @@ -51,11 +86,11 @@ def parse_elf_header(): | |||
| 51 | 86 | ||
| 52 | if arch == 32: | 87 | if arch == 32: | 
| 53 | # 32bit | 88 | # 32bit | 
| 54 | hdr_fmt = "<HHILLLIHHHHHH" | 89 | hdr_fmt = endian_prefix + "HHILLLIHHHHHH" | 
| 55 | hdr_size = 52 | 90 | hdr_size = 52 | 
| 56 | else: | 91 | else: | 
| 57 | # 64bit | 92 | # 64bit | 
| 58 | hdr_fmt = "<HHIQQQIHHHHHH" | 93 | hdr_fmt = endian_prefix + "HHIQQQIHHHHHH" | 
| 59 | hdr_size = 64 | 94 | hdr_size = 64 | 
| 60 | 95 | ||
| 61 | e_type, e_machine, e_version, e_entry, e_phoff, e_shoff, e_flags,\ | 96 | e_type, e_machine, e_version, e_entry, e_phoff, e_shoff, e_flags,\ | 
| @@ -64,9 +99,9 @@ def parse_elf_header(): | |||
| 64 | 99 | ||
| 65 | def change_interpreter(elf_file_name): | 100 | def change_interpreter(elf_file_name): | 
| 66 | if arch == 32: | 101 | if arch == 32: | 
| 67 | ph_fmt = "<IIIIIIII" | 102 | ph_fmt = endian_prefix + "IIIIIIII" | 
| 68 | else: | 103 | else: | 
| 69 | ph_fmt = "<IIQQQQQQ" | 104 | ph_fmt = endian_prefix + "IIQQQQQQ" | 
| 70 | 105 | ||
| 71 | """ look for PT_INTERP section """ | 106 | """ look for PT_INTERP section """ | 
| 72 | for i in range(0,e_phnum): | 107 | for i in range(0,e_phnum): | 
| @@ -97,25 +132,26 @@ def change_interpreter(elf_file_name): | |||
| 97 | if (len(new_dl_path) >= p_filesz): | 132 | if (len(new_dl_path) >= p_filesz): | 
| 98 | print("ERROR: could not relocate %s, interp size = %i and %i is needed." \ | 133 | print("ERROR: could not relocate %s, interp size = %i and %i is needed." \ | 
| 99 | % (elf_file_name, p_memsz, len(new_dl_path) + 1)) | 134 | % (elf_file_name, p_memsz, len(new_dl_path) + 1)) | 
| 100 | break | 135 | return False | 
| 101 | dl_path = new_dl_path + b("\0") * (p_filesz - len(new_dl_path)) | 136 | dl_path = new_dl_path + b("\0") * (p_filesz - len(new_dl_path)) | 
| 102 | f.seek(p_offset) | 137 | f.seek(p_offset) | 
| 103 | f.write(dl_path) | 138 | f.write(dl_path) | 
| 104 | break | 139 | break | 
| 140 | return True | ||
| 105 | 141 | ||
| 106 | def change_dl_sysdirs(elf_file_name): | 142 | def change_dl_sysdirs(elf_file_name): | 
| 107 | if arch == 32: | 143 | if arch == 32: | 
| 108 | sh_fmt = "<IIIIIIIIII" | 144 | sh_fmt = endian_prefix + "IIIIIIIIII" | 
| 109 | else: | 145 | else: | 
| 110 | sh_fmt = "<IIQQQQIIQQ" | 146 | sh_fmt = endian_prefix + "IIQQQQIIQQ" | 
| 111 | 147 | ||
| 112 | """ read section string table """ | 148 | """ read section string table """ | 
| 113 | f.seek(e_shoff + e_shstrndx * e_shentsize) | 149 | f.seek(e_shoff + e_shstrndx * e_shentsize) | 
| 114 | sh_hdr = f.read(e_shentsize) | 150 | sh_hdr = f.read(e_shentsize) | 
| 115 | if arch == 32: | 151 | if arch == 32: | 
| 116 | sh_offset, sh_size = struct.unpack("<16xII16x", sh_hdr) | 152 | sh_offset, sh_size = struct.unpack(endian_prefix + "16xII16x", sh_hdr) | 
| 117 | else: | 153 | else: | 
| 118 | sh_offset, sh_size = struct.unpack("<24xQQ24x", sh_hdr) | 154 | sh_offset, sh_size = struct.unpack(endian_prefix + "24xQQ24x", sh_hdr) | 
| 119 | 155 | ||
| 120 | f.seek(sh_offset) | 156 | f.seek(sh_offset) | 
| 121 | sh_strtab = f.read(sh_size) | 157 | sh_strtab = f.read(sh_size) | 
| @@ -215,6 +251,9 @@ else: | |||
| 215 | 251 | ||
| 216 | executables_list = sys.argv[3:] | 252 | executables_list = sys.argv[3:] | 
| 217 | 253 | ||
| 254 | dl_arch = get_dl_arch(new_dl_path) | ||
| 255 | |||
| 256 | errors = False | ||
| 218 | for e in executables_list: | 257 | for e in executables_list: | 
| 219 | perms = os.stat(e)[stat.ST_MODE] | 258 | perms = os.stat(e)[stat.ST_MODE] | 
| 220 | if os.access(e, os.W_OK|os.R_OK): | 259 | if os.access(e, os.W_OK|os.R_OK): | 
| @@ -238,9 +277,10 @@ for e in executables_list: | |||
| 238 | old_size = os.path.getsize(e) | 277 | old_size = os.path.getsize(e) | 
| 239 | if old_size >= 64: | 278 | if old_size >= 64: | 
| 240 | arch = get_arch() | 279 | arch = get_arch() | 
| 241 | if arch: | 280 | if arch and arch == dl_arch: | 
| 242 | parse_elf_header() | 281 | parse_elf_header() | 
| 243 | change_interpreter(e) | 282 | if not change_interpreter(e): | 
| 283 | errors = True | ||
| 244 | change_dl_sysdirs(e) | 284 | change_dl_sysdirs(e) | 
| 245 | 285 | ||
| 246 | """ change permissions back """ | 286 | """ change permissions back """ | 
| @@ -253,3 +293,6 @@ for e in executables_list: | |||
| 253 | print("New file size for %s is different. Looks like a relocation error!", e) | 293 | print("New file size for %s is different. Looks like a relocation error!", e) | 
| 254 | sys.exit(-1) | 294 | sys.exit(-1) | 
| 255 | 295 | ||
| 296 | if errors: | ||
| 297 | print("Relocation of one or more executables failed.") | ||
| 298 | sys.exit(-1) | ||
