diff --git a/amitools/binfmt/BinImage.py b/amitools/binfmt/BinImage.py index 2796fa02..a32670e6 100644 --- a/amitools/binfmt/BinImage.py +++ b/amitools/binfmt/BinImage.py @@ -13,14 +13,18 @@ class Reloc: - def __init__(self, offset, width=2, addend=0): + def __init__(self, offset, type, width=2, addend=0): self.offset = offset + self.type = type self.width = width self.addend = addend def get_offset(self): return self.offset + def get_type(self): + return self.type + def get_width(self): return self.width diff --git a/amitools/binfmt/Relocate.py b/amitools/binfmt/Relocate.py index 9567b273..2bd080d0 100644 --- a/amitools/binfmt/Relocate.py +++ b/amitools/binfmt/Relocate.py @@ -74,6 +74,7 @@ def _copy_data(self, data, segment, offset=0): def _reloc_data(self, data, segment, addrs, offset=0): # find relocations to_segs = segment.get_reloc_to_segs() + my_addr = addrs[segment.id] for to_seg in to_segs: # get target segment's address to_id = to_seg.id @@ -81,13 +82,18 @@ def _reloc_data(self, data, segment, addrs, offset=0): # get relocations reloc = segment.get_reloc(to_seg) for r in reloc.get_relocs(): - self._reloc(segment.id, data, r, to_addr, to_id, offset) + self._reloc(segment.id, data, r, my_addr, to_addr, to_id, offset) - def _reloc(self, my_id, data, reloc, to_addr, to_id, extra_offset): + def _reloc(self, my_id, data, reloc, my_addr, to_addr, to_id, extra_offset): """relocate one entry""" offset = reloc.get_offset() + extra_offset delta = self._read_long(data, offset) + reloc.addend - addr = to_addr + delta + if reloc.get_type() == 1: + addr = to_addr + delta + elif reloc.get_type() == 4: + addr = delta + to_addr - my_addr - offset + else: + raise(Exception("unsupported type %d" % reloc.get_type())) self._write_long(data, offset, addr) if self.verbose: print( diff --git a/amitools/binfmt/elf/BinFmtELF.py b/amitools/binfmt/elf/BinFmtELF.py index b425096b..f8b3470e 100644 --- a/amitools/binfmt/elf/BinFmtELF.py +++ b/amitools/binfmt/elf/BinFmtELF.py @@ -1,6 +1,7 @@ -from amitools.binfmt.BinImage import * -from .ELFFile import * -from .ELF import * +from amitools.binfmt.BinImage import BIN_IMAGE_TYPE_ELF, SEGMENT_TYPE_CODE, SEGMENT_TYPE_DATA, SEGMENT_FLAG_READ_ONLY, SEGMENT_TYPE_BSS, Segment, Relocations,\ + SymbolTable, Symbol, Reloc, DebugLine, DebugLineFile, DebugLineEntry, BinImage +from .ELFFile import ELFIdentifier, ELFHeader, ELFParseError +from .ELF import EM_68K, ELFOSABI_AROS, ELFOSABI_SYSV from .ELFReader import ELFReader from .DwarfDebugLine import DwarfDebugLine @@ -60,19 +61,18 @@ def load_image_fobj(self, fobj): # walk through elf sections sect_to_seg = {} for sect in elf.sections: + if sect.header.type_ == 0 or sect.header.type_ == 4: + continue # determine segment type seg_type = None name = sect.name_str flags = 0 - if name == b".text": + if name.startswith(b".text"): seg_type = SEGMENT_TYPE_CODE - elif name == b".data": - seg_type = SEGMENT_TYPE_DATA - elif name == b".rodata": - seg_type = SEGMENT_TYPE_DATA - flags = SEGMENT_FLAG_READ_ONLY elif name == b".bss": seg_type = SEGMENT_TYPE_BSS + else: + seg_type = SEGMENT_TYPE_DATA # we got a segment if seg_type is not None: size = sect.header.size @@ -118,7 +118,7 @@ def add_elf_rela(self, sect, seg, sect_to_seg): seg.add_reloc(to_seg, rl) # add relocations for rel in sect.get_rela_by_section(tgt_sect): - r = Reloc(rel.offset, addend=rel.section_addend) + r = Reloc(rel.offset, rel.type_, addend=rel.section_addend) rl.add_reloc(r) def add_elf_symbols(self, symbols, seg): diff --git a/amitools/binfmt/elf/ELF.py b/amitools/binfmt/elf/ELF.py index 709dcf0d..913d41d6 100644 --- a/amitools/binfmt/elf/ELF.py +++ b/amitools/binfmt/elf/ELF.py @@ -65,4 +65,4 @@ STV_values = {0: "DEFAULT", 1: "INTERNAL", 2: "HIDDEN", 3: "PROTECTED"} -R_68K_values = {0: "68K_NONE", 1: "68K_32"} +R_68K_values = {0: "68K_NONE", 1: "68K_32", 4: "68K_PC32"} diff --git a/amitools/binfmt/elf/ELFFile.py b/amitools/binfmt/elf/ELFFile.py index 0518468e..1e25a3f8 100644 --- a/amitools/binfmt/elf/ELFFile.py +++ b/amitools/binfmt/elf/ELFFile.py @@ -122,6 +122,7 @@ def __init__(self, header, idx): self.symbols = [] self.relocations = None self.reloc_by_sect = {} + self.bss = None def get_rela(self): """return a list with all relocations""" diff --git a/amitools/binfmt/elf/ELFReader.py b/amitools/binfmt/elf/ELFReader.py index d2dc450a..9939972a 100644 --- a/amitools/binfmt/elf/ELFReader.py +++ b/amitools/binfmt/elf/ELFReader.py @@ -1,6 +1,5 @@ """A class for reading and writing ELF format binaries (esp. Amiga m68k ones)""" -import struct import os from .ELF import * from .ELFFile import * @@ -25,6 +24,8 @@ def _load_sections(self, f, ef): idx += 1 sect = self._load_section(f, sect_hdr, idx) ef.sections.append(sect) + if sect_hdr.type_ == SHT_NOBITS: + ef.bss = sect def _load_section(self, f, sect_hdr, idx): t = sect_hdr.type_ @@ -62,17 +63,22 @@ def _resolve_symtab_names(self, sect, sections): raise ELFParseError("Invalid strtab for symtab: " + strtab_seg_num) strtab = sections[strtab_seg_num] if strtab.__class__ != ELFSectionStringTable: - raise ELFParserError("Invalid strtab segment for symtab") + raise ELFParseError("Invalid strtab segment for symtab") # resolve all symbol names for sym in sect.symtab: sym.name_str = strtab.get_string(sym.name) - def _resolve_symtab_indices(self, sect, sections): + def _resolve_symtab_indices(self, sect, ef, sections): for sym in sect.symtab: if sym.shndx_str == None: # refers a valid section idx = sym.shndx - sym.section = sections[idx] + if idx == 65522: # common + sym.section = ef.bss + sym.value = ef.bss.header.size + ef.bss.header.size += sym.size + 3 & ~3 + else: + sym.section = sections[idx] def _assign_symbols_to_sections(self, sect): src_file_sym = None @@ -196,7 +202,7 @@ def load(self, f): # get names in symtab self._resolve_symtab_names(sect, ef.sections) # link sections to symbols - self._resolve_symtab_indices(sect, ef.sections) + self._resolve_symtab_indices(sect, ef, ef.sections) # assign symbols to sections self._assign_symbols_to_sections(sect) diff --git a/amitools/binfmt/hunk/BinFmtHunk.py b/amitools/binfmt/hunk/BinFmtHunk.py index 47339456..a6fbd50c 100644 --- a/amitools/binfmt/hunk/BinFmtHunk.py +++ b/amitools/binfmt/hunk/BinFmtHunk.py @@ -166,7 +166,7 @@ def _add_hunk_relocs(self, blks, seg, all_segs): rl = Relocations(to_seg) # add offsets for o in offsets: - r = Reloc(o) + r = Reloc(o, 1) rl.add_reloc(r) seg.add_reloc(to_seg, rl)