Skip to content

Commit

Permalink
ELF reader fixes and enhancements (@bebbo #151)
Browse files Browse the repository at this point in the history
  • Loading branch information
cnvogelg committed Mar 4, 2021
1 parent 34db20c commit 18fe317
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 21 deletions.
6 changes: 5 additions & 1 deletion amitools/binfmt/BinImage.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 9 additions & 3 deletions amitools/binfmt/Relocate.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,26 @@ 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
to_addr = addrs[to_id]
# 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(
Expand Down
20 changes: 10 additions & 10 deletions amitools/binfmt/elf/BinFmtELF.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion amitools/binfmt/elf/ELF.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
1 change: 1 addition & 0 deletions amitools/binfmt/elf/ELFFile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand Down
16 changes: 11 additions & 5 deletions amitools/binfmt/elf/ELFReader.py
Original file line number Diff line number Diff line change
@@ -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 *
Expand All @@ -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_
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion amitools/binfmt/hunk/BinFmtHunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 18fe317

Please sign in to comment.