Files
codezero/tools/pyelf/readelf.py
Bahadir Balban 7a388f22b7 Removed all ignorable files from git.
Previously python hex() would put an extra 'L' after printing out the
value and this would be trimmed in readelf.py. Now it doesn't seem to
do that so the lsd of the number was trimmed. This patch fixes that.
2008-01-14 12:23:40 +00:00

129 lines
4.9 KiB
Python
Executable File

#!/usr/bin/env python
from aistruct import AIStruct
import elf, sys
from optparse import OptionParser
from os import path
class AfterBurner(AIStruct):
def __init__(self, *args, **kwargs):
AIStruct.__init__(self, AIStruct.SIZE32)
self.setup(
('UINT32', 'addr')
)
def __str__(self):
return "0x%x" % self.ai.addr.get()
def main():
parser = OptionParser(add_help_option=False)
parser.add_option("-h", "--file-header",
action="store_true", dest="header", default=False,
help="Display the ELF file header")
parser.add_option("-l", "--program-headers",
action="store_true", dest="program_headers", default=False,
help="Display the program headers")
parser.add_option("-S", "--section-headers",
action="store_true", dest="section_headers", default=False,
help="Display the section headers")
parser.add_option("--afterburn",
action="store_true", dest="afterburn", default=False,
help="Display the afterburn relocations")
parser.add_option("--first-free-page",
action="store_true", dest="ffpage", default=False,
help="Prints out (in .lds format) the address of the first free physical" + \
"page after this image at load time. Using this information at link" + \
"time, images can be compiled and linked consecutively and loaded in" + \
"consecutive memory regions at load time.")
parser.add_option("--lma-start-end", action="store_true", dest="lma_boundary", default=False,
help="Prints out the start and end LMA boundaries of an image." + \
"This is useful for autogenerating a structure for the microkernel" + \
"to discover at run-time where svc tasks are loaded.")
(options, args) = parser.parse_args()
if len(args) != 1:
parser.print_help()
return
elffile = elf.ElfFile.from_file(args[0])
if options.header:
print elffile.header
if options.program_headers:
print elffile.pheaders
if options.section_headers:
print elffile.sheaders
if options.afterburn:
burnheader = elffile.sheaders[".afterburn"]
burns = burnheader.container(AfterBurner)
print "There are %d afterburn entry points" % len(burns)
print "Afterburn:"
for burn in burns:
print " ", burn
if options.lma_boundary:
paddr_first = 0
paddr_start = 0
paddr_end = 0
for pheader in elffile.pheaders:
x = pheader.ai
if str(x.p_type) != "LOAD":
continue
# First time assign the first p_paddr.
if paddr_first == 0:
paddr_first = 1
paddr_start = x.p_paddr.value
# Then if new paddr is lesser, reassign start.
if paddr_start > x.p_paddr.value:
paddr_start = x.p_paddr.value
# If end of segment is greater, reassign end.
if paddr_end < x.p_paddr + x.p_memsz:
paddr_end = x.p_paddr + x.p_memsz
rest, image_name = path.split(args[0])
if image_name[-4] == ".":
image_name = image_name[:-4]
print image_name
if hex(paddr_start)[-1] == "L":
print "image_start " + hex(paddr_start)[:-1]
else:
print "image_start " + hex(paddr_start)
if hex(paddr_end)[-1] == "L":
print "image_end " + hex(paddr_end)[:-1]
else:
print "image_end " + hex(paddr_end)
if options.ffpage:
paddr_max = 0
p_align = 0
for pheader in elffile.pheaders:
x = pheader.ai
if str(x.p_type) == "LOAD":
paddr = x.p_paddr + x.p_memsz
p_align = x.p_align
if paddr > paddr_max:
paddr_max = paddr
print "/*\n" + \
" * The next free p_align'ed LMA base address\n" + \
" *\n" + \
" * p_align = " + hex(p_align.value) + "\n" + \
" *\n" + \
" * Recap from ELF spec: p_align: Loadable process segments must have\n" + \
" * congruent values for p_vaddr and p_offset, modulo the page size. \n" + \
" * This member gives the value to which the segments are aligned in \n" + \
" * memory and in the file. Values 0 and 1 mean that no alignment is \n" + \
" * required. Otherwise, p_align should be a positive, integral power\n" + \
" * of 2, and p_addr should equal p_offset, modulo p_align. \n" + \
" * This essentially means next available address must be aligned at\n" + \
" * p_align, rather than the page_size, which one (well, I) would \n" + \
" * normally expect. \n" + \
" */\n"
paddr_aligned = paddr_max & ~(p_align.value - 1)
if paddr_max & (p_align.value - 1):
paddr_aligned += p_align.value
if hex(paddr_aligned)[-1] == "L":
print "physical_base = " + hex(paddr_aligned)[:-1] + ";"
else:
print "physical_base = " + hex(paddr_aligned) + ";"
if __name__ == "__main__":
main()