Esempio n. 1
0
 def get_relocate_entries(elf_file):
     entries=[]
     readelf_relocs_process=subprocess.Popen([SDK.arm_tool("readelf"),'-r',elf_file],stdout=subprocess.PIPE)
     readelf_relocs_output=readelf_relocs_process.communicate()[0].decode("utf-8")
     lines=readelf_relocs_output.splitlines()
     i=0
     reading_section=False
     while i<len(lines):
         if not reading_section:
             if lines[i].startswith("Relocation section '.rel.data"):
                 reading_section=True
                 i+=1
         else:
             if len(lines[i])==0:
                 reading_section=False
             else:
                 entries.append(int(lines[i].split(' ')[0],16))
         i+=1
     readelf_relocs_process=subprocess.Popen([SDK.arm_tool("readelf"),'--sections',elf_file],stdout=subprocess.PIPE)
     readelf_relocs_output=readelf_relocs_process.communicate()[0].decode("utf-8")
     lines=readelf_relocs_output.splitlines()
     for line in lines:
         if'.got'in line and'.got.plt'not in line:
             words=line.split(' ')
             while''in words:
                 words.remove('')
             section_label_idx=words.index('.got')
             addr=int(words[section_label_idx+2],16)
             length=int(words[section_label_idx+4],16)
             for i in range(addr,addr+length,4):
                 entries.append(i)
             break
     return entries
Esempio n. 2
0
 def __init__(self, name, arch, max_binary_size, max_memory_size, cflags=[], fallback_platforms=[], directory=""):
     self.name = name
     self.arch = arch
     self.includes = [SDK.include_path(name)]
     self.lib = os.path.join(SDK.lib_path(name), "libpebble.a")
     self.max_binary_size = max_binary_size
     self.max_memory_size = max_memory_size
     self.cflags = cflags
     self._syscall_table = None # Lazy-loaded
     self._patched = False
     self.fallback_platforms = fallback_platforms
     self.directory = directory
Esempio n. 3
0
    def _compile(self, infiles, outfile, cflags=None, linkflags=None):
        if not hasattr(infiles, "__iter__"):
            infiles = [infiles]

        cflags = cflags if cflags else []
        linkflags = linkflags if linkflags else []

        if "-c" not in cflags: # To avoid the harmless warning
            infiles = infiles + [self._platform.lib]
        # Common flags
        cflags = [  "-mcpu=%s" % self._platform.arch,
                    "-mthumb",
                    "-fPIC",
                    "-fPIE",
                    "-ffunction-sections",
                    "-fdata-sections",
                    "-std=c99",
                    "-Os",
                    "-nostdlib"] + ["-I%s" % path for path in self._platform.includes] + cflags
        if self._platform.cflags:
            cflags = cflags + self._platform.cflags

        linkflags = ["-e_entry",
                     "--gc-sections"] + linkflags

        linkflags = ["-Wl,%s" % flag for flag in linkflags] # Since we're letting gcc link too
        cmd = [SDK.arm_tool("gcc")] + cflags + linkflags + ["-o", outfile] + infiles
        logger.debug("Compiling with %s" % cmd)
        compile_proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        result, _ = compile_proc.communicate()
        if compile_proc.poll():
            raise CompilationError("Compilation failed:\n%s" % result)
Esempio n. 4
0
 def syscall_table(self):
     if not self._syscall_table:
         self._syscall_table = {}
         libpebble_dsm_output = subprocess.check_output([SDK.arm_tool("objdump"), "-d", self.lib]).decode("utf-8")
         for call_match in re.finditer(r"<(?P<fcn>[^>]+)>:(?:\n.+){4}8:\s*(?P<idx>[0-9a-f]{8})", libpebble_dsm_output):
             self._syscall_table[call_match.group("fcn")] = int(call_match.group("idx"), 16)
         logger.info("Read %d syscall table entries for %s", len(self.syscall_table.items()), self.name)
     return self._syscall_table
Esempio n. 5
0
 def _compile_mod_bin(self, infiles, intermdiatefile, outfile, app_addr, bss_addr, bss_section="BSS", cflags=None):
     ldfile_template = open(os.path.join(os.path.dirname(__file__), "mods_layout.template.ld"), "r").read()
     ldfile_template = check_replace(ldfile_template, "@BSS@", hex(bss_addr)) # The end of their BSS, plus what we'll insert
     ldfile_template = check_replace(ldfile_template, "@BSS_SECTION@", bss_section) # Where to put it at all
     ldfile_template = check_replace(ldfile_template, "@APP@", hex(app_addr)) # Where the rest of the app will get mounted
     ldfile_out_path = os.path.join(self._scratch_dir, "mods.ld")
     map_out_path = os.path.join(self._scratch_dir, "mods.map")
     open(ldfile_out_path, "w").write(ldfile_template)
     self._compile(infiles, intermdiatefile, linkflags=["-T" + ldfile_out_path, "-Map,%s,--emit-relocs" % map_out_path], cflags=cflags)
     subprocess.check_call([SDK.arm_tool("objcopy"), "-S", "-R", ".stack", "-R", ".priv_bss", "-R", ".bss", "-O", "binary", intermdiatefile, outfile])
Esempio n. 6
0
 def _get_nm_output(self, elf_file, raw=False):
     # This is from the SDK
     nm_process=subprocess.Popen([SDK.arm_tool("nm"),elf_file],stdout=subprocess.PIPE)
     nm_output=nm_process.communicate()[0]
     if not nm_output:
         raise BinaryPatcher.EmptyBinaryError()
     nm_output = nm_output.decode("utf-8")
     if raw:
         return nm_output
     nm_output=[line.split()for line in nm_output.splitlines()]
     return nm_output
Esempio n. 7
0
 def get_virtual_size(elf_file):
     readelf_bss_process=subprocess.Popen([SDK.arm_tool("readelf"), "-S", elf_file], stdout=subprocess.PIPE)
     readelf_bss_output=readelf_bss_process.communicate()[0].decode("utf-8")
     last_section_end_addr=0
     for line in readelf_bss_output.splitlines():
         if len(line)<10:
             continue
         line=line[6:]
         columns=line.split()
         if len(columns)<6:
             continue
         if columns[0]=='.bss':
             addr=int(columns[2],16)
             size=int(columns[4],16)
             last_section_end_addr=addr+size
         elif columns[0]=='.data'and last_section_end_addr==0:
             addr=int(columns[2],16)
             size=int(columns[4],16)
             last_section_end_addr=addr+size
     if last_section_end_addr!=0:
         return last_section_end_addr
     raise Exception("Failed to parse ELF sections while calculating the virtual size", readelf_bss_output)