mirror of
https://github.com/espressif/esptool.git
synced 2025-10-18 18:01:15 +08:00
fix(elf2image): add ELF flags to merge condition
Improve the condition upon the segments being merged in the elf2image command. Covering the cases when comparing adjacent segment addresses and types is not enough. Signed-off-by: Marek Matej <marek.matej@espressif.com>
This commit is contained in:
@@ -115,10 +115,11 @@ class ImageSegment(object):
|
||||
"""Wrapper class for a segment in an ESP image
|
||||
(very similar to a section in an ELFImage also)"""
|
||||
|
||||
def __init__(self, addr, data, file_offs=None):
|
||||
def __init__(self, addr, data, file_offs=None, flags=0):
|
||||
self.addr = addr
|
||||
self.data = data
|
||||
self.file_offs = file_offs
|
||||
self.flags = flags
|
||||
self.include_in_checksum = True
|
||||
if self.addr != 0:
|
||||
self.pad_to_alignment(
|
||||
@@ -167,8 +168,8 @@ class ELFSection(ImageSegment):
|
||||
"""Wrapper class for a section in an ELF image, has a section
|
||||
name as well as the common properties of an ImageSegment."""
|
||||
|
||||
def __init__(self, name, addr, data):
|
||||
super(ELFSection, self).__init__(addr, data)
|
||||
def __init__(self, name, addr, data, flags):
|
||||
super(ELFSection, self).__init__(addr, data, flags=flags)
|
||||
self.name = name.decode("utf-8")
|
||||
|
||||
def __repr__(self):
|
||||
@@ -178,6 +179,9 @@ class ELFSection(ImageSegment):
|
||||
class BaseFirmwareImage(object):
|
||||
SEG_HEADER_LEN = 8
|
||||
SHA256_DIGEST_LEN = 32
|
||||
ELF_FLAG_WRITE = 0x1
|
||||
ELF_FLAG_READ = 0x2
|
||||
ELF_FLAG_EXEC = 0x4
|
||||
|
||||
""" Base class with common firmware image functions """
|
||||
|
||||
@@ -373,6 +377,8 @@ class BaseFirmwareImage(object):
|
||||
elem.get_memory_type(self) == next_elem.get_memory_type(self),
|
||||
elem.include_in_checksum == next_elem.include_in_checksum,
|
||||
next_elem.addr == elem.addr + len(elem.data),
|
||||
next_elem.flags & self.ELF_FLAG_EXEC
|
||||
== elem.flags & self.ELF_FLAG_EXEC,
|
||||
)
|
||||
):
|
||||
# Merge any segment that ends where the next one starts,
|
||||
@@ -1276,7 +1282,7 @@ class ELFFile(object):
|
||||
name_offs, sec_type, _flags, lma, sec_offs, size = struct.unpack_from(
|
||||
"<LLLLLL", section_header[offs:]
|
||||
)
|
||||
return (name_offs, sec_type, lma, size, sec_offs)
|
||||
return (name_offs, sec_type, lma, size, sec_offs, _flags)
|
||||
|
||||
all_sections = [read_section_header(offs) for offs in section_header_offsets]
|
||||
prog_sections = [s for s in all_sections if s[1] in ELFFile.PROG_SEC_TYPES]
|
||||
@@ -1285,7 +1291,7 @@ class ELFFile(object):
|
||||
# search for the string table section
|
||||
if (shstrndx * self.LEN_SEC_HEADER) not in section_header_offsets:
|
||||
raise FatalError("ELF file has no STRTAB section at shstrndx %d" % shstrndx)
|
||||
_, sec_type, _, sec_size, sec_offs = read_section_header(
|
||||
_, sec_type, _, sec_size, sec_offs, _ = read_section_header(
|
||||
shstrndx * self.LEN_SEC_HEADER
|
||||
)
|
||||
if sec_type != ELFFile.SEC_TYPE_STRTAB:
|
||||
@@ -1307,14 +1313,14 @@ class ELFFile(object):
|
||||
return f.read(size)
|
||||
|
||||
prog_sections = [
|
||||
ELFSection(lookup_string(n_offs), lma, read_data(offs, size))
|
||||
for (n_offs, _type, lma, size, offs) in prog_sections
|
||||
ELFSection(lookup_string(n_offs), lma, read_data(offs, size), flags=_flags)
|
||||
for (n_offs, _type, lma, size, offs, _flags) in prog_sections
|
||||
if lma != 0 and size > 0
|
||||
]
|
||||
self.sections = prog_sections
|
||||
self.nobits_sections = [
|
||||
ELFSection(lookup_string(n_offs), lma, b"")
|
||||
for (n_offs, _type, lma, size, offs) in nobits_secitons
|
||||
ELFSection(lookup_string(n_offs), lma, b"", flags=_flags)
|
||||
for (n_offs, _type, lma, size, offs, _flags) in nobits_secitons
|
||||
if lma != 0 and size > 0
|
||||
]
|
||||
|
||||
@@ -1347,7 +1353,7 @@ class ELFFile(object):
|
||||
_flags,
|
||||
_align,
|
||||
) = struct.unpack_from("<LLLLLLLL", segment_header[offs:])
|
||||
return (seg_type, lma, size, seg_offs)
|
||||
return (seg_type, lma, size, seg_offs, _flags)
|
||||
|
||||
all_segments = [read_segment_header(offs) for offs in segment_header_offsets]
|
||||
prog_segments = [s for s in all_segments if s[0] == ELFFile.SEG_TYPE_LOAD]
|
||||
@@ -1357,8 +1363,8 @@ class ELFFile(object):
|
||||
return f.read(size)
|
||||
|
||||
prog_segments = [
|
||||
ELFSection(b"PHDR", lma, read_data(offs, size))
|
||||
for (_type, lma, size, offs) in prog_segments
|
||||
ELFSection(b"PHDR", lma, read_data(offs, size), flags=_flags)
|
||||
for (_type, lma, size, offs, _flags) in prog_segments
|
||||
if lma != 0 and size > 0
|
||||
]
|
||||
self.segments = prog_segments
|
||||
|
@@ -697,7 +697,7 @@ def write_flash(esp, args):
|
||||
print("Flash md5: %s" % res)
|
||||
print(
|
||||
"MD5 of 0xFF is %s"
|
||||
% (hashlib.md5(b"\xFF" * uncsize).hexdigest())
|
||||
% (hashlib.md5(b"\xff" * uncsize).hexdigest())
|
||||
)
|
||||
raise FatalError("MD5 of file does not match data in flash!")
|
||||
else:
|
||||
@@ -1383,7 +1383,7 @@ def merge_bin(args):
|
||||
|
||||
def pad_to(flash_offs):
|
||||
# account for output file offset if there is any
|
||||
of.write(b"\xFF" * (flash_offs - args.target_offset - of.tell()))
|
||||
of.write(b"\xff" * (flash_offs - args.target_offset - of.tell()))
|
||||
|
||||
for addr, argfile in input_files:
|
||||
pad_to(addr)
|
||||
|
@@ -326,8 +326,8 @@ class TestESP32Image(BaseTestCase):
|
||||
# this ELF will produce 8 segments in the bin
|
||||
image = self._test_elf2image(ELF, BIN)
|
||||
# Adjacent sections are now merged, len(image.segments) should
|
||||
# equal 4 (instead of 8).
|
||||
assert len(image.segments) == 4
|
||||
# equal 5 (instead of 8).
|
||||
assert len(image.segments) == 5
|
||||
|
||||
# --use_segments uses ELF segments(phdrs), produces just 2 segments in the bin
|
||||
image = self._test_elf2image(ELF, BIN, ["--use_segments"])
|
||||
|
Reference in New Issue
Block a user