in test-snapshot-binaries/linux_load_commands.py [0:0]
def process_library(args, lib):
assert(len(lib) > 0)
numberOfLines = None
numberOfLinesSeen = 0
print("Visiting lib: {}".format(lib))
lines = list(reversed(subprocess.check_output([args.read_elf, "--program-headers", lib], universal_newlines=True).split("\n")[:-1]))
p = ParseState()
# Until we finish parsing or run out of lines to parse...
while len(lines) > 0:
l = lines.pop()
print("DUMP: '{}'".format(l))
assert(p is not None)
curState = p
m = curState.matches(l)
if m is None:
continue
p = curState.next
if curState.value == ParseState.firstLine:
numberOfLines = int(m.group(1))
continue
if curState.value == ParseState.programHeadersLine:
continue
if curState.value == ParseState.dataHeader:
continue
if curState.value == ParseState.data:
val = m.group(1)
if val == "LOAD":
flags = m.group(2)
print("Found LOAD command! Flags: '{}'. Full match: '{}'".format(flags, l))
if "W" in flags and "E" in flags:
raise RuntimeError("Found a load command that loads something executable and writeable")
# If we haven't seen enough lines, continue.
assert(numberOfLines is not None)
if numberOfLinesSeen != numberOfLines - 1:
numberOfLinesSeen += 1
continue
# If we have seen enough lines, be sure to not only break out
# of the switch, but additionally break out of the whole
# parsing loop. We could go through the rest of the output from
# llvm-readelf, but there isn't any point.
p = None
break
# If we ran out of lines to parse without finishing parsing, we failed.
assert(p is None)
assert(numberOfLines is not None)
assert(numberOfLinesSeen == numberOfLines - 1)