How to use sections method in fMBT

Best Python code snippet using fMBT_python

layoutrom.py

Source:layoutrom.py Github

copy

Full Screen

1#!/usr/bin/env python2# Script to analyze code and arrange ld sections.3#4# Copyright (C) 2008-2014 Kevin O'Connor <kevin@koconnor.net>5#6# This file may be distributed under the terms of the GNU GPLv3 license.7import operator8import sys9# LD script headers/trailers10COMMONHEADER = """11/* DO NOT EDIT! This is an autogenerated file. See scripts/layoutrom.py. */12OUTPUT_FORMAT("elf32-i386")13OUTPUT_ARCH("i386")14SECTIONS15{16"""17COMMONTRAILER = """18 /* Discard regular data sections to force a link error if19 * code attempts to access data not marked with VAR16 (or other20 * appropriate macro)21 */22 /DISCARD/ : {23 *(.text*) *(.data*) *(.bss*) *(.rodata*)24 *(COMMON) *(.discard*) *(.eh_frame) *(.note*)25 }26}27"""28######################################################################29# Determine section locations30######################################################################31# Align 'pos' up to 'alignbytes' offset32def alignpos(pos, alignbytes):33 mask = alignbytes - 134 return (pos + mask) & ~mask35# Align 'pos' down to 'alignbytes' offset36def aligndown(pos, alignbytes):37 mask = alignbytes - 138 return pos & ~mask39# Determine the final addresses for a list of sections that end at an40# address.41def setSectionsStart(sections, endaddr, minalign=1, segoffset=0):42 totspace = 043 for section in sections:44 minalign = max(minalign, section.align)45 totspace = alignpos(totspace, section.align) + section.size46 startaddr = int((endaddr - totspace) / minalign) * minalign47 curaddr = startaddr48 for section in sections:49 curaddr = alignpos(curaddr, section.align)50 section.finalloc = curaddr51 section.finalsegloc = curaddr - segoffset52 curaddr += section.size53 return startaddr, minalign54# The 16bit code can't exceed 64K of space.55BUILD_BIOS_ADDR = 0xf000056BUILD_BIOS_SIZE = 0x1000057BUILD_ROM_START = 0xc000058BUILD_LOWRAM_END = 0xa000059# Space to reserve in f-segment for dynamic allocations60BUILD_MIN_BIOSTABLE = 204861# Layout the 16bit code. This ensures sections with fixed offset62# requirements are placed in the correct location. It also places the63# 16bit code as high as possible in the f-segment.64def fitSections(sections, fillsections):65 # fixedsections = [(addr, section), ...]66 fixedsections = []67 for section in sections:68 if section.name.startswith('.fixedaddr.'):69 addr = int(section.name[11:], 16)70 section.finalloc = addr + BUILD_BIOS_ADDR71 section.finalsegloc = addr72 fixedsections.append((addr, section))73 if section.align != 1:74 print("Error: Fixed section %s has non-zero alignment (%d)" % (75 section.name, section.align))76 sys.exit(1)77 fixedsections.sort(key=operator.itemgetter(0))78 firstfixed = fixedsections[0][0]79 # Find freespace in fixed address area80 # fixedAddr = [(freespace, section), ...]81 fixedAddr = []82 for i in range(len(fixedsections)):83 fixedsectioninfo = fixedsections[i]84 addr, section = fixedsectioninfo85 if i == len(fixedsections) - 1:86 nextaddr = BUILD_BIOS_SIZE87 else:88 nextaddr = fixedsections[i+1][0]89 avail = nextaddr - addr - section.size90 fixedAddr.append((avail, section))91 fixedAddr.sort(key=operator.itemgetter(0))92 # Attempt to fit other sections into fixed area93 canrelocate = [(section.size, section.align, section.name, section)94 for section in fillsections]95 canrelocate.sort()96 canrelocate = [section for size, align, name, section in canrelocate]97 totalused = 098 for freespace, fixedsection in fixedAddr:99 addpos = fixedsection.finalsegloc + fixedsection.size100 totalused += fixedsection.size101 nextfixedaddr = addpos + freespace102# print("Filling section %x uses %d, next=%x, available=%d" % (103# fixedsection.finalloc, fixedsection.size, nextfixedaddr, freespace))104 while 1:105 canfit = None106 for fitsection in canrelocate:107 if addpos + fitsection.size > nextfixedaddr:108 # Can't fit and nothing else will fit.109 break110 fitnextaddr = alignpos(addpos, fitsection.align) + fitsection.size111# print("Test %s - %x vs %x" % (112# fitsection.name, fitnextaddr, nextfixedaddr))113 if fitnextaddr > nextfixedaddr:114 # This item can't fit.115 continue116 canfit = (fitnextaddr, fitsection)117 if canfit is None:118 break119 # Found a section that can fit.120 fitnextaddr, fitsection = canfit121 canrelocate.remove(fitsection)122 fitsection.finalloc = addpos + BUILD_BIOS_ADDR123 fitsection.finalsegloc = addpos124 addpos = fitnextaddr125 totalused += fitsection.size126# print(" Adding %s (size %d align %d) pos=%x avail=%d" % (127# fitsection[2], fitsection[0], fitsection[1]128# , fitnextaddr, nextfixedaddr - fitnextaddr))129 # Report stats130 total = BUILD_BIOS_SIZE-firstfixed131 slack = total - totalused132 print ("Fixed space: 0x%x-0x%x total: %d slack: %d"133 " Percent slack: %.1f%%" % (134 firstfixed, BUILD_BIOS_SIZE, total, slack,135 (float(slack) / total) * 100.0))136 return firstfixed + BUILD_BIOS_ADDR137# Return the subset of sections with a given category138def getSectionsCategory(sections, category):139 return [section for section in sections if section.category == category]140# Return the subset of sections with a given fileid141def getSectionsFileid(sections, fileid):142 return [section for section in sections if section.fileid == fileid]143# Return the subset of sections with a given name prefix144def getSectionsPrefix(sections, prefix):145 return [section for section in sections146 if section.name.startswith(prefix)]147# The sections (and associated information) to be placed in output rom148class LayoutInfo:149 sections = None150 config = None151 genreloc = None152 sec32init_start = sec32init_end = sec32init_align = None153 sec32low_start = sec32low_end = None154 zonelow_base = final_sec32low_start = None155 zonefseg_start = zonefseg_end = None156 final_readonly_start = None157 varlowsyms = entrysym = None158# Determine final memory addresses for sections159def doLayout(sections, config, genreloc):160 li = LayoutInfo()161 li.config = config162 li.sections = sections163 li.genreloc = genreloc164 # Determine 16bit positions165 sections16 = getSectionsCategory(sections, '16')166 textsections = getSectionsPrefix(sections16, '.text.')167 rodatasections = getSectionsPrefix(sections16, '.rodata')168 datasections = getSectionsPrefix(sections16, '.data16.')169 fixedsections = getSectionsCategory(sections, 'fixed')170 firstfixed = fitSections(fixedsections, textsections)171 remsections = [s for s in textsections+rodatasections+datasections172 if s.finalloc is None]173 sec16_start, sec16_align = setSectionsStart(174 remsections, firstfixed, segoffset=BUILD_BIOS_ADDR)175 # Determine 32seg positions176 sections32seg = getSectionsCategory(sections, '32seg')177 textsections = getSectionsPrefix(sections32seg, '.text.')178 rodatasections = getSectionsPrefix(sections32seg, '.rodata')179 datasections = getSectionsPrefix(sections32seg, '.data32seg.')180 sec32seg_start, sec32seg_align = setSectionsStart(181 textsections + rodatasections + datasections, sec16_start182 , segoffset=BUILD_BIOS_ADDR)183 # Determine 32bit "fseg memory" data positions184 sections32textfseg = getSectionsCategory(sections, '32textfseg')185 sec32textfseg_start, sec32textfseg_align = setSectionsStart(186 sections32textfseg, sec32seg_start, 16)187 sections32fseg = getSectionsCategory(sections, '32fseg')188 sec32fseg_start, sec32fseg_align = setSectionsStart(189 sections32fseg, sec32textfseg_start, 16190 , segoffset=BUILD_BIOS_ADDR)191 # Determine 32flat runtime positions192 sections32flat = getSectionsCategory(sections, '32flat')193 textsections = getSectionsPrefix(sections32flat, '.text.')194 rodatasections = getSectionsPrefix(sections32flat, '.rodata')195 datasections = getSectionsPrefix(sections32flat, '.data.')196 bsssections = getSectionsPrefix(sections32flat, '.bss.')197 sec32flat_start, sec32flat_align = setSectionsStart(198 textsections + rodatasections + datasections + bsssections199 , sec32fseg_start, 16)200 # Determine 32flat init positions201 sections32init = getSectionsCategory(sections, '32init')202 init32_textsections = getSectionsPrefix(sections32init, '.text.')203 init32_rodatasections = getSectionsPrefix(sections32init, '.rodata')204 init32_datasections = getSectionsPrefix(sections32init, '.data.')205 init32_bsssections = getSectionsPrefix(sections32init, '.bss.')206 sec32init_start, sec32init_align = setSectionsStart(207 init32_textsections + init32_rodatasections208 + init32_datasections + init32_bsssections209 , sec32flat_start, 16)210 # Determine location of ZoneFSeg memory.211 zonefseg_end = sec32flat_start212 if not genreloc:213 zonefseg_end = sec32init_start214 zonefseg_start = BUILD_BIOS_ADDR215 if zonefseg_start + BUILD_MIN_BIOSTABLE > zonefseg_end:216 # Not enough ZoneFSeg space - force a minimum space.217 zonefseg_end = sec32fseg_start218 zonefseg_start = zonefseg_end - BUILD_MIN_BIOSTABLE219 sec32flat_start, sec32flat_align = setSectionsStart(220 textsections + rodatasections + datasections + bsssections221 , zonefseg_start, 16)222 sec32init_start, sec32init_align = setSectionsStart(223 init32_textsections + init32_rodatasections224 + init32_datasections + init32_bsssections225 , sec32flat_start, 16)226 li.sec32init_start = sec32init_start227 li.sec32init_end = sec32flat_start228 li.sec32init_align = sec32init_align229 final_readonly_start = min(BUILD_BIOS_ADDR, sec32flat_start)230 if not genreloc:231 final_readonly_start = min(BUILD_BIOS_ADDR, sec32init_start)232 li.zonefseg_start = zonefseg_start233 li.zonefseg_end = zonefseg_end234 li.final_readonly_start = final_readonly_start235 # Determine "low memory" data positions236 sections32low = getSectionsCategory(sections, '32low')237 sec32low_end = sec32init_start238 if config.get('CONFIG_MALLOC_UPPERMEMORY'):239 final_sec32low_end = final_readonly_start240 zonelow_base = final_sec32low_end - 64*1024241 zonelow_base = max(BUILD_ROM_START, alignpos(zonelow_base, 2*1024))242 else:243 final_sec32low_end = BUILD_LOWRAM_END244 zonelow_base = final_sec32low_end - 64*1024245 relocdelta = final_sec32low_end - sec32low_end246 li.sec32low_start, sec32low_align = setSectionsStart(247 sections32low, sec32low_end, 16248 , segoffset=zonelow_base - relocdelta)249 li.sec32low_end = sec32low_end250 li.zonelow_base = zonelow_base251 li.final_sec32low_start = li.sec32low_start + relocdelta252 # Print statistics253 size16 = BUILD_BIOS_ADDR + BUILD_BIOS_SIZE - sec16_start254 size32seg = sec16_start - sec32seg_start255 size32textfseg = sec32seg_start - sec32textfseg_start256 size32fseg = sec32textfseg_start - sec32fseg_start257 size32flat = sec32fseg_start - sec32flat_start258 size32init = sec32flat_start - sec32init_start259 sizelow = li.sec32low_end - li.sec32low_start260 print("16bit size: %d" % size16)261 print("32bit segmented size: %d" % size32seg)262 print("32bit flat size: %d" % (size32flat + size32textfseg))263 print("32bit flat init size: %d" % size32init)264 print("Lowmem size: %d" % sizelow)265 print("f-segment var size: %d" % size32fseg)266 return li267######################################################################268# Linker script output269######################################################################270# Write LD script includes for the given cross references271def outXRefs(sections, useseg=0, exportsyms=[], forcedelta=0):272 xrefs = dict([(symbol.name, symbol) for symbol in exportsyms])273 out = ""274 for section in sections:275 for reloc in section.relocs:276 symbol = reloc.symbol277 if (symbol.section is not None278 and (symbol.section.fileid != section.fileid279 or symbol.name != reloc.symbolname)):280 xrefs[reloc.symbolname] = symbol281 for symbolname, symbol in xrefs.items():282 loc = symbol.section.finalloc283 if useseg:284 loc = symbol.section.finalsegloc285 out += "%s = 0x%x ;\n" % (symbolname, loc + forcedelta + symbol.offset)286 return out287# Write LD script includes for the given sections288def outSections(sections, useseg=0):289 out = ""290 for section in sections:291 loc = section.finalloc292 if useseg:293 loc = section.finalsegloc294 out += "%s 0x%x : { *(%s) }\n" % (section.name, loc, section.name)295 return out296# Write LD script includes for the given sections using relative offsets297def outRelSections(sections, startsym, useseg=0):298 sections = [(section.finalloc, section) for section in sections299 if section.finalloc is not None]300 sections.sort(key=operator.itemgetter(0))301 out = ""302 for addr, section in sections:303 loc = section.finalloc304 if useseg:305 loc = section.finalsegloc306 out += ". = ( 0x%x - %s ) ;\n" % (loc, startsym)307 if section.name in ('.rodata.str1.1', '.rodata'):308 out += "_rodata%s = . ;\n" % (section.fileid,)309 out += "*%s.*(%s)\n" % (section.fileid, section.name)310 return out311# Build linker script output for a list of relocations.312def strRelocs(outname, outrel, relocs):313 relocs.sort()314 return (" %s_start = ABSOLUTE(.) ;\n" % (outname,)315 + "".join(["LONG(0x%x - %s)\n" % (pos, outrel)316 for pos in relocs])317 + " %s_end = ABSOLUTE(.) ;\n" % (outname,))318# Find relocations to the given sections319def getRelocs(sections, tosection, type=None):320 return [section.finalloc + reloc.offset321 for section in sections322 for reloc in section.relocs323 if (reloc.symbol.section in tosection324 and (type is None or reloc.type == type))]325# Output the linker scripts for all required sections.326def writeLinkerScripts(li, out16, out32seg, out32flat):327 # Write 16bit linker script328 filesections16 = getSectionsFileid(li.sections, '16')329 out = outXRefs(filesections16, useseg=1) + """330 zonelow_base = 0x%x ;331 _zonelow_seg = 0x%x ;332%s333""" % (li.zonelow_base,334 int(li.zonelow_base / 16),335 outSections(filesections16, useseg=1))336 outfile = open(out16, 'w')337 outfile.write(COMMONHEADER + out + COMMONTRAILER)338 outfile.close()339 # Write 32seg linker script340 filesections32seg = getSectionsFileid(li.sections, '32seg')341 out = (outXRefs(filesections32seg, useseg=1)342 + outSections(filesections32seg, useseg=1))343 outfile = open(out32seg, 'w')344 outfile.write(COMMONHEADER + out + COMMONTRAILER)345 outfile.close()346 # Write 32flat linker script347 sec32all_start = li.sec32low_start348 relocstr = ""349 if li.genreloc:350 # Generate relocations351 initsections = dict([352 (s, 1) for s in getSectionsCategory(li.sections, '32init')])353 noninitsections = dict([(s, 1) for s in li.sections354 if s not in initsections])355 absrelocs = getRelocs(initsections, initsections, type='R_386_32')356 relrelocs = getRelocs(initsections, noninitsections, type='R_386_PC32')357 initrelocs = getRelocs(noninitsections, initsections)358 relocstr = (strRelocs("_reloc_abs", "code32init_start", absrelocs)359 + strRelocs("_reloc_rel", "code32init_start", relrelocs)360 + strRelocs("_reloc_init", "code32flat_start", initrelocs))361 numrelocs = len(absrelocs + relrelocs + initrelocs)362 sec32all_start -= numrelocs * 4363 filesections32flat = getSectionsFileid(li.sections, '32flat')364 out = outXRefs([], exportsyms=li.varlowsyms365 , forcedelta=li.final_sec32low_start-li.sec32low_start)366 multiboot_header = ""367 if li.config.get('CONFIG_MULTIBOOT'):368 multiboot_header = "LONG(0x1BADB002) LONG(0) LONG(-0x1BADB002)"369 sec32all_start -= 3 * 4370 sec32all_align = max([section.align for section in li.sections])371 sec32all_start = aligndown(sec32all_start, sec32all_align)372 out += outXRefs(filesections32flat, exportsyms=[li.entrysym]) + """373 _reloc_min_align = 0x%x ;374 zonefseg_start = 0x%x ;375 zonefseg_end = 0x%x ;376 zonelow_base = 0x%x ;377 final_varlow_start = 0x%x ;378 final_readonly_start = 0x%x ;379 varlow_start = 0x%x ;380 varlow_end = 0x%x ;381 code32init_start = 0x%x ;382 code32init_end = 0x%x ;383 code32flat_start = 0x%x ;384 .text code32flat_start : {385%s386%s387%s388 code32flat_end = ABSOLUTE(.) ;389 } :text390""" % (li.sec32init_align,391 li.zonefseg_start,392 li.zonefseg_end,393 li.zonelow_base,394 li.final_sec32low_start,395 li.final_readonly_start,396 li.sec32low_start,397 li.sec32low_end,398 li.sec32init_start,399 li.sec32init_end,400 sec32all_start,401 multiboot_header,402 relocstr,403 outRelSections(li.sections, 'code32flat_start'))404 out = COMMONHEADER + out + COMMONTRAILER + """405ENTRY(%s)406PHDRS407{408 text PT_LOAD AT ( code32flat_start ) ;409}410""" % (li.entrysym.name,)411 outfile = open(out32flat, 'w')412 outfile.write(out)413 outfile.close()414######################################################################415# Detection of unused sections and init sections416######################################################################417# Visit all sections reachable from a given set of start sections418def findReachable(anchorsections, checkreloc, data):419 anchorsections = dict([(section, []) for section in anchorsections])420 pending = list(anchorsections)421 while pending:422 section = pending.pop()423 for reloc in section.relocs:424 chain = anchorsections[section] + [section.name]425 if not checkreloc(reloc, section, data, chain):426 continue427 nextsection = reloc.symbol.section428 if nextsection not in anchorsections:429 anchorsections[nextsection] = chain430 pending.append(nextsection)431 return anchorsections432# Find "runtime" sections (ie, not init only sections).433def checkRuntime(reloc, rsection, data, chain):434 section = reloc.symbol.section435 if section is None or '.init.' in section.name:436 return 0437 if '.data.varinit.' in section.name:438 print("ERROR: %s is VARVERIFY32INIT but used from %s" % (439 section.name, chain))440 sys.exit(1)441 return 1442# Find and keep the section associated with a symbol (if available).443def checkKeepSym(reloc, syms, fileid, isxref):444 symbolname = reloc.symbolname445 mustbecfunc = symbolname.startswith('_cfunc')446 if mustbecfunc:447 symprefix = '_cfunc' + fileid + '_'448 if not symbolname.startswith(symprefix):449 return 0450 symbolname = symbolname[len(symprefix):]451 symbol = syms.get(symbolname)452 if (symbol is None or symbol.section is None453 or symbol.section.name.startswith('.discard.')):454 return 0455 isdestcfunc = (symbol.section.name.startswith('.text.')456 and not symbol.section.name.startswith('.text.asm.'))457 if ((mustbecfunc and not isdestcfunc)458 or (not mustbecfunc and isdestcfunc and isxref)):459 return 0460 reloc.symbol = symbol461 return 1462# Resolve a relocation and check if it should be kept in the final binary.463def checkKeep(reloc, section, symbols, chain):464 ret = checkKeepSym(reloc, symbols[section.fileid], section.fileid, 0)465 if ret:466 return ret467 # Not in primary sections - it may be a cross 16/32 reference468 for fileid in ('16', '32seg', '32flat'):469 if fileid != section.fileid:470 ret = checkKeepSym(reloc, symbols[fileid], fileid, 1)471 if ret:472 return ret473 return 0474######################################################################475# Startup and input parsing476######################################################################477class Section:478 name = size = alignment = fileid = relocs = None479 finalloc = finalsegloc = category = None480class Reloc:481 offset = type = symbolname = symbol = None482class Symbol:483 name = offset = section = None484# Read in output from objdump485def parseObjDump(file, fileid):486 # sections = [section, ...]487 sections = []488 sectionmap = {}489 # symbols[symbolname] = symbol490 symbols = {}491 state = None492 for line in file.readlines():493 line = line.rstrip()494 if line == 'Sections:':495 state = 'section'496 continue497 if line == 'SYMBOL TABLE:':498 state = 'symbol'499 continue500 if line.startswith('RELOCATION RECORDS FOR ['):501 sectionname = line[24:-2]502 if sectionname.startswith('.debug_'):503 # Skip debugging sections (to reduce parsing time)504 state = None505 continue506 state = 'reloc'507 relocsection = sectionmap[sectionname]508 continue509 if state == 'section':510 try:511 idx, name, size, vma, lma, fileoff, align = line.split()512 if align[:3] != '2**':513 continue514 section = Section()515 section.name = name516 section.size = int(size, 16)517 section.align = 2**int(align[3:])518 section.fileid = fileid519 section.relocs = []520 sections.append(section)521 sectionmap[name] = section522 except ValueError:523 pass524 continue525 if state == 'symbol':526 try:527 parts = line[17:].split()528 if len(parts) == 3:529 sectionname, size, name = parts530 elif len(parts) == 4 and parts[2] == '.hidden':531 sectionname, size, hidden, name = parts532 else:533 continue534 symbol = Symbol()535 symbol.size = int(size, 16)536 symbol.offset = int(line[:8], 16)537 symbol.name = name538 symbol.section = sectionmap.get(sectionname)539 symbols[name] = symbol540 except ValueError:541 pass542 continue543 if state == 'reloc':544 try:545 off, type, symbolname = line.split()546 reloc = Reloc()547 reloc.offset = int(off, 16)548 reloc.type = type549 reloc.symbolname = symbolname550 reloc.symbol = symbols.get(symbolname)551 if reloc.symbol is None:552 # Some binutils (2.20.1) give section name instead553 # of a symbol - create a dummy symbol.554 reloc.symbol = symbol = Symbol()555 symbol.size = 0556 symbol.offset = 0557 symbol.name = symbolname558 symbol.section = sectionmap.get(symbolname)559 symbols[symbolname] = symbol560 relocsection.relocs.append(reloc)561 except ValueError:562 pass563 return sections, symbols564# Parser for constants in simple C header files.565def scanconfig(file):566 f = open(file, 'r')567 opts = {}568 for l in f.readlines():569 parts = l.split()570 if len(parts) != 3:571 continue572 if parts[0] != '#define':573 continue574 value = parts[2]575 if value.isdigit() or (value.startswith('0x') and value[2:].isdigit()):576 value = int(value, 0)577 opts[parts[1]] = value578 return opts579def main():580 # Get output name581 in16, in32seg, in32flat, cfgfile, out16, out32seg, out32flat = sys.argv[1:]582 # Read in the objdump information583 infile16 = open(in16, 'r')584 infile32seg = open(in32seg, 'r')585 infile32flat = open(in32flat, 'r')586 # infoX = (sections, symbols)587 info16 = parseObjDump(infile16, '16')588 info32seg = parseObjDump(infile32seg, '32seg')589 info32flat = parseObjDump(infile32flat, '32flat')590 # Read kconfig config file591 config = scanconfig(cfgfile)592 # Figure out which sections to keep.593 allsections = info16[0] + info32seg[0] + info32flat[0]594 symbols = {'16': info16[1], '32seg': info32seg[1], '32flat': info32flat[1]}595 if config.get('CONFIG_COREBOOT'):596 entrysym = symbols['16'].get('entry_elf')597 elif config.get('CONFIG_CSM'):598 entrysym = symbols['16'].get('entry_csm')599 else:600 entrysym = symbols['16'].get('reset_vector')601 anchorsections = [entrysym.section] + [602 section for section in allsections603 if section.name.startswith('.fixedaddr.')]604 keepsections = findReachable(anchorsections, checkKeep, symbols)605 sections = [section for section in allsections if section in keepsections]606 # Separate 32bit flat into runtime, init, and special variable parts607 anchorsections = [608 section for section in sections609 if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name610 or '.fixedaddr.' in section.name or '.runtime.' in section.name)]611 runtimesections = findReachable(anchorsections, checkRuntime, None)612 for section in sections:613 if section.name.startswith('.data.varlow.'):614 section.category = '32low'615 elif section.name.startswith('.data.varfseg.'):616 section.category = '32fseg'617 elif section.name.startswith('.text.32fseg.'):618 section.category = '32textfseg'619 elif section.name.startswith('.fixedaddr.'):620 section.category = 'fixed'621 elif section.fileid == '32flat' and section not in runtimesections:622 section.category = '32init'623 else:624 section.category = section.fileid625 # Determine the final memory locations of each kept section.626 genreloc = '_reloc_abs_start' in symbols['32flat']627 li = doLayout(sections, config, genreloc)628 # Exported symbols629 li.varlowsyms = [symbol for symbol in symbols['32flat'].values()630 if (symbol.section is not None631 and symbol.section.finalloc is not None632 and '.data.varlow.' in symbol.section.name633 and symbol.name != symbol.section.name)]634 li.entrysym = entrysym635 # Write out linker script files.636 writeLinkerScripts(li, out16, out32seg, out32flat)637if __name__ == '__main__':...

Full Screen

Full Screen

connect_cross_sections.py

Source:connect_cross_sections.py Github

copy

Full Screen

...8 9function: connect_cross_sections_without_indication(10 workspace, in_cross_sections, out_cross_sections_name, maximum_distance)11 12function: check_duplicated_cross_sections(in_cross_sections)13 14"""15import logging16import math17import time18import arcpy19from configuration.configure_logging import create_logger20from other.list_field_names import list_field_names21logger = logging.getLogger(__name__)22create_logger(logger)23def connect_cross_sections_with_indication(24 workspace, in_cross_sections, out_cross_sections_name, line_field,25 maximum_distance):26 """Connect the points from the cross sections to lines.27 28 An indication (e.g. a kilometer indication) is used as line field29 for the connection. If the named line_field is not avaiable, the30 function connect_cross_sections_without_indication is called. 31 Else, after connecting the cross sections, a field 'SECTIONID'32 and a field 'INTERMEDIATEID' are added to the output feature class.33 The SECTIONID begins with 1 and is incremented. The INTERMEDIATEID34 is set to 0.35 36 @param workspace (DEWorkspace):37 The workspace for results.38 @param in_cross_sections (DEFeatureClass): 39 The feature class with the cross sections points.40 @param out_cross_sections out_cross_sections (GPString): 41 The output feature class name.42 @param line_field (GPString): 43 The line fields name.44 @param maximum_distance (GPDouble):45 The maximum distance between points.46 47 @return out_cross_sections(DEFeatureClass): 48 The output cross section feature class.49 50 """ 51 logger.debug("Check if line_field '" + line_field +"' exists.")52 field_names = list_field_names(in_cross_sections)53 54 if line_field in field_names: 55 logger.debug("Start connecting cross sections to lines.")56 try:57 out_cross_sections = workspace + "/" + out_cross_sections_name58 arcpy.PointsToLine_management(59 in_cross_sections, out_cross_sections, line_field60 )61 except arcpy.ExecuteError:62 logger.warning(63 out_cross_sections + " already exists. Change output name: " 64 + out_cross_sections + time.strftime("%d%m%y_%H%M%S.")65 )66 out_cross_sections = (67 out_cross_sections + time.strftime("%d%m%y_%H%M%S")68 )69 arcpy.PointsToLine_management(70 in_cross_sections, out_cross_sections, line_field71 )72 logger.info("Connecting cross sections completed successfully.")73 logger.debug("Add a field SECTIONID.")74 field_name = "SECTIONID"75 field_type = "SHORT"76 arcpy.AddField_management(out_cross_sections, field_name, field_type)77 logger.info("Field SECTIONID added successfully.")78 79 logger.debug("Add a field INTERMEDIATEID.")80 field_name = "INTERMEDIATEID"81 arcpy.AddField_management(out_cross_sections, field_name, field_type)82 logger.info("Field INTERMEDIATEID added successfully.")83 84 logger.debug("Create cursor for allocating the IDs.")85 field_names = ["SECTIONID", "INTERMEDIATEID"]86 with arcpy.da.UpdateCursor(out_cross_sections, field_names) as cursor:87 i = 188 for row in cursor:89 row[0] = i90 row[1] = 091 cursor.updateRow(row)92 i = i + 193 logger.info(94 "Set SECTIONID successfully: " + str (i) + " cross sections "95 "exist. Set INTERMEDIATEID successfully to 0."96 )97 return out_cross_sections98 99 else:100 logger.warning(101 "Line_field '" + line_field + "' does not exist. Start function "102 "connect_cross_sections_without_indication."103 )104 out_cross_sections = connect_cross_sections_without_indication(105 workspace, in_cross_sections, out_cross_sections_name,106 maximum_distance107 )108 109 return out_cross_sections110 111def connect_cross_sections_without_indication(112 workspace, in_cross_sections, out_cross_sections_name,113 maximum_distance):114 """Connect the points from the cross sections to lines.115 116 The function arcpy.PointsToLine_management(in_features,117 out_features, line_field) needs a line_field to connect points which118 belong together. For this, a line_field is created in this function.119 Therefore a field 'SECTIONID' is added to the in_cross_section120 feature class. Then, the coordinates of the points are transfered121 into point_list with a cursor. After that, the distance between122 successive points is computed. If the distance is less than the 123 maximum_distance, the cursor sets the SECTIONID for the point to the124 current value (starts with 1). If the maximum_distance is greater than125 the distance, the next distance is not computed. The point after126 next and the following points with a distance less maximum_distance get127 a SECTIONID + 1. After computing all distances between successive 128 points in this way, the SECTIONID is used as line field for the129 connection. After connecting the cross sections, a field 130 'INTERMEDIATEID' is added to the output feature class and set to 0131 with a cursor. 132 133 @param workspace (DEWorkspace): 134 The workspace for results.135 @param in_cross_sections (DEFeatureClass): 136 The feature class with the cross sections points.137 @param out_cross_sections (GPString): 138 The output feature class name.139 @param maximum_distance (GPDouble): 140 The maximum distance between points.141 142 @return out_cross_sections(DEFeatureClass): 143 The output cross section feature class.144 145 """ 146 logger.debug("Add a field SECTIONID.")147 field_name = "SECTIONID"148 field_type = "SHORT"149 arcpy.AddField_management(in_cross_sections, field_name, field_type)150 logger.info("Field SECTIONID added successfully.")151 logger.debug("Transfer coordinates into list point_list.")152 point_list = []153 field_names = ["SHAPE@X", "SHAPE@Y", "SHAPE@Z", "SECTIONID"]154 with arcpy.da.UpdateCursor(in_cross_sections, field_names) as cursor:155 for row in cursor: 156 point_list.append([row[0], row[1], row[2]])157 logger.info(str(len(point_list)) + " points transferred into point_list.")158 159 cursor.reset()160 logger.debug("Start creating the line_field SECTIONID.")161 i = 0162 j = 1163 for row in cursor:164 if i < (len(point_list) - 1):165 distance = (166 math.sqrt(math.pow(point_list[i + 1][0] - point_list[i][0], 2) 167 + math.pow(point_list[i + 1][1] - point_list[i][1], 2)168 + math.pow(point_list[i + 1][2] - point_list[i][2], 2))169 )170 row[3] = j171 cursor.updateRow(row)172 if distance > maximum_distance:173 j = j + 1174 i = i + 1175 logger.info("Set SECTIONID successfully until " + str (j) + ".")176 logger.debug("Start connecting cross sections to lines.")177 try:178 out_cross_sections = workspace + "/" + out_cross_sections_name179 line_field = "SECTIONID"180 arcpy.PointsToLine_management(181 in_cross_sections, out_cross_sections, line_field182 )183 except arcpy.ExecuteError:184 logger.warning(185 out_cross_sections + " already exists. Change output name: " 186 + out_cross_sections + time.strftime("%d%m%y_%H%M%S.")187 )188 out_cross_sections = (189 out_cross_sections + time.strftime("%d%m%y_%H%M%S")190 )191 arcpy.PointsToLine_management(192 in_cross_sections, out_cross_sections, line_field193 )194 logger.info("Connecting cross sections completed successfully.")195 196 logger.debug("Add a field INTERMEDIATEID.")197 field_name = "INTERMEDIATEID"198 arcpy.AddField_management(out_cross_sections, field_name, field_type)199 logger.info("Field INTERMEDIATEID added successfully.") 200 logger.debug("Create cursor for allocating the IDs.")201 field_names = ["INTERMEDIATEID"] 202 with arcpy.da.UpdateCursor(out_cross_sections, field_names) as cursor:203 for row in cursor:204 row[0] = 0205 cursor.updateRow(row)206 logger.info("Set INTERMEDIATEID successfully to 0.")207 208 return out_cross_sections209def check_duplicated_cross_sections(in_cross_sections):210 """Check if duplicated cross sections exist and delete one of them.211 212 First, the total number of cross sections is counted. A feature213 layer is created to select successive cross sections. For the214 selected cross sections it is checked, if their center is in the 215 other cross section. In this case the number of selected layers is216 2, otherwise the number is 1. If the number is 2, one of the two 217 cross sections (the first) is deleted. Finally, it is checked if 218 this case occured at all. If this is true, the SECTIONID is 219 adjusted to the correct values.220 221 @param in_cross_sections (DEFeatureClass): 222 The feature class with the cross sections.223 ...

Full Screen

Full Screen

sections.js

Source:sections.js Github

copy

Full Screen

1// (C) Copyright 2015 Martin Dougiamas2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14angular.module('mm.core.course')15/**16 * Sections view controller.17 *18 * @module mm.core.course19 * @ngdoc controller20 * @name mmCourseSectionsCtrl21 */22.controller('mmCourseSectionsCtrl', function($mmCourse, $mmUtil, $scope, $stateParams, $translate, $mmCourseHelper, $mmEvents,23 $mmSite, $mmCoursePrefetchDelegate, $mmCourses, $q, $ionicHistory, $ionicPlatform, mmCoreCourseAllSectionsId,24 mmCoreEventSectionStatusChanged, $state, $timeout, $mmCoursesDelegate, $controller) {25 var courseId = $stateParams.courseid,26 sectionId = $stateParams.sid,27 moduleId = $stateParams.moduleid,28 course = $stateParams.course ? angular.copy($stateParams.course) : false;29 $scope.courseId = courseId;30 $scope.sectionToLoad = 2; // Load "General" section by default.31 $scope.fullname = course.fullname || "";32 $scope.downloadSectionsEnabled = $mmCourseHelper.isDownloadSectionsEnabled();33 $scope.downloadSectionsIcon = getDownloadSectionIcon();34 $scope.sectionHasContent = $mmCourseHelper.sectionHasContent;35 $scope.courseActions = [];36 function loadSections(refresh) {37 var promise;38 if (course) {39 promise = $q.when();40 } else {41 // We don't have the course name, get it.42 promise = $mmCourses.getUserCourse(courseId).catch(function() {43 // Fail, maybe user isn't enrolled but he has capabilities to view it.44 return $mmCourses.getCourse(courseId);45 }).then(function(courseResponse) {46 course = courseResponse;47 return course.fullname;48 }).catch(function() {49 // Fail again, return generic value.50 return $translate.instant('mm.core.course');51 });52 }53 return promise.then(function(courseFullName) {54 if (courseFullName) {55 $scope.fullname = courseFullName;56 }57 // Load course actions in background.58 $mmCoursesDelegate.getNavHandlersForCourse(course, refresh, true).then(function(buttons) {59 $scope.courseActions = buttons.map(function(button) {60 var newScope = $scope.$new();61 $controller(button.controller, {$scope: newScope});62 var buttonInfo = {63 text: $translate.instant(newScope.title),64 icon: newScope.icon || false,65 priority: button.priority || false,66 action: function() {67 // Fake event (already prevented) to avoid errors on app.68 var ev = document.createEvent("MouseEvent");69 return newScope.action(ev, course);70 }71 };72 newScope.$destroy();73 return buttonInfo;74 });75 });76 // Get the sections.77 return $mmCourse.getSections(courseId, false, true).then(function(sections) {78 sections = sections.map(function(section) {79 section.name = section.name.trim() || section.section;80 return section;81 });82 // Add a fake first section (all sections).83 var result = [{84 name: $translate.instant('mm.course.allsections'),85 id: mmCoreCourseAllSectionsId86 }].concat(sections);87 $scope.sections = result;88 if ($scope.downloadSectionsEnabled) {89 calculateSectionStatus(refresh);90 }91 });92 }).catch(function(error) {93 $mmUtil.showErrorModalDefault(error, 'mm.course.couldnotloadsections', true);94 });95 }96 $scope.toggleDownloadSections = function() {97 $scope.downloadSectionsEnabled = !$scope.downloadSectionsEnabled;98 $mmCourseHelper.setDownloadSectionsEnabled($scope.downloadSectionsEnabled);99 $scope.downloadSectionsIcon = getDownloadSectionIcon();100 if ($scope.downloadSectionsEnabled) {101 calculateSectionStatus(false);102 }103 };104 // Convenience function to calculate icon for the contextual menu.105 function getDownloadSectionIcon() {106 return $scope.downloadSectionsEnabled ? 'ion-android-checkbox-outline' : 'ion-android-checkbox-outline-blank';107 }108 // Calculate status of the sections. We don't return the promise because109 // we don't want to block the rendering of the sections.110 function calculateSectionStatus(refresh) {111 $mmCourseHelper.calculateSectionsStatus($scope.sections, $scope.courseId, true, refresh).catch(function() {112 // Ignore errors (shouldn't happen).113 }).then(function(downloadpromises) {114 // If we restored any download we'll recalculate the status once all of them have finished.115 if (downloadpromises && downloadpromises.length) {116 $mmUtil.allPromises(downloadpromises).catch(function() {117 if (!$scope.$$destroyed) {118 $mmUtil.showErrorModal('mm.course.errordownloadingsection', true);119 }120 }).finally(function() {121 if (!$scope.$$destroyed) {122 // Recalculate the status.123 $mmCourseHelper.calculateSectionsStatus($scope.sections, $scope.courseId, false);124 }125 });126 }127 });128 }129 // Prefetch a section. The second parameter indicates if the prefetch was started manually (true)130 // or it was automatically started because all modules are being downloaded (false).131 function prefetch(section, manual) {132 $mmCourseHelper.prefetch(section, courseId, $scope.sections).catch(function() {133 // Don't show error message if scope is destroyed or it's an automatic download but we aren't in this state.134 if ($scope.$$destroyed) {135 return;136 }137 var current = $ionicHistory.currentStateName(),138 isCurrent = ($ionicPlatform.isTablet() && current == 'site.mm_course.mm_course-section') ||139 (!$ionicPlatform.isTablet() && current == 'site.mm_course');140 if (!manual && !isCurrent) {141 return;142 }143 $mmUtil.showErrorModal('mm.course.errordownloadingsection', true);144 }).finally(function() {145 if (!$scope.$$destroyed) {146 // Recalculate the status.147 $mmCourseHelper.calculateSectionsStatus($scope.sections, courseId, false);148 }149 });150 }151 // Convenience function to autoload a section if sectionId param is set.152 function autoloadSection() {153 if (sectionId) {154 if ($ionicPlatform.isTablet()) {155 // Search the position of the section to load.156 angular.forEach($scope.sections, function(section, index) {157 if (section.id == sectionId) {158 $scope.sectionToLoad = index + 1;159 }160 });161 // Set moduleId to pass it to the new state when the section is autoloaded. We unset it after this162 // to prevent autoloading the module when the user manually loads a section.163 $scope.moduleId = moduleId;164 $timeout(function() {165 $scope.moduleId = null; // Unset moduleId when166 }, 500);167 } else {168 $state.go('site.mm_course-section', {169 sectionid: sectionId,170 cid: courseId,171 mid: moduleId172 });173 }174 }175 }176 $scope.doRefresh = function() {177 var promises = [];178 promises.push($mmCourses.invalidateUserCourses());179 promises.push($mmCourse.invalidateSections(courseId));180 if ($scope.sections && $scope.downloadSectionsEnabled) {181 // Invalidate modules prefetch data.182 var modules = $mmCourseHelper.getSectionsModules($scope.sections);183 promises.push($mmCoursePrefetchDelegate.invalidateModules(modules, courseId));184 }185 promises.push($mmCoursesDelegate.clearAndInvalidateCoursesOptions(courseId));186 $q.all(promises).finally(function() {187 loadSections(true).finally(function() {188 $scope.$broadcast('scroll.refreshComplete');189 });190 });191 };192 $scope.prefetch = function(e, section) {193 e.preventDefault();194 e.stopPropagation();195 section.isCalculating = true;196 $mmCourseHelper.confirmDownloadSize(courseId, section, $scope.sections).then(function() {197 prefetch(section, true);198 }).finally(function() {199 section.isCalculating = false;200 });201 };202 loadSections().finally(function() {203 autoloadSection();204 $scope.sectionsLoaded = true;205 });206 // Listen for section status changes.207 var statusObserver = $mmEvents.on(mmCoreEventSectionStatusChanged, function(data) {208 if ($scope.downloadSectionsEnabled && $scope.sections && $scope.sections.length && data.siteid === $mmSite.getId() &&209 !$scope.$$destroyed && data.sectionid) {210 // Check if the affected section is being downloaded. If so, we don't update section status211 // because it'll already be updated when the download finishes.212 if ($mmCoursePrefetchDelegate.isBeingDownloaded($mmCourseHelper.getSectionDownloadId({id: data.sectionid}))) {213 return;214 }215 // Recalculate the status.216 $mmCourseHelper.calculateSectionsStatus($scope.sections, courseId, false).then(function() {217 var section;218 angular.forEach($scope.sections, function(s) {219 if (s.id === data.sectionid) {220 section = s;221 }222 });223 if (section) {224 var downloadid = $mmCourseHelper.getSectionDownloadId(section);225 if (section.isDownloading && !$mmCoursePrefetchDelegate.isBeingDownloaded(downloadid)) {226 // All the modules are now downloading, set a download all promise.227 prefetch(section, false);228 }229 }230 });231 }232 });233 $scope.$on('$destroy', function() {234 statusObserver && statusObserver.off && statusObserver.off();235 });...

Full Screen

Full Screen

section-config.test.js

Source:section-config.test.js Github

copy

Full Screen

1/**2 * Copyright © Magento, Inc. All rights reserved.3 * See COPYING.txt for license details.4 */5/* eslint max-nested-callbacks: 0 */6define(['squire'], function (Squire) {7 'use strict';8 var injector = new Squire(),9 obj;10 beforeEach(function (done) {11 // injector.mock(mocks);12 injector.require(['Magento_Customer/js/section-config'], function (Constr) {13 obj = Constr;14 done();15 });16 });17 afterEach(function () {18 try {19 injector.clean();20 injector.remove();21 } catch (e) {}22 });23 describe('Magento_Customer/js/section-config', function () {24 describe('"getAffectedSections" method', function () {25 it('Does not throw before component is initialized.', function () {26 expect(function () {27 obj.getAffectedSections('http://localhost.com/path');28 }).not.toThrow();29 });30 it('Returns proper sections when URL contains base URL.', function () {31 obj['Magento_Customer/js/section-config']({32 sections: {33 'path': [34 'section'35 ]36 },37 baseUrls: [38 'http://localhost.com/',39 'https://localhost.com/'40 ]41 });42 expect(obj.getAffectedSections('https://localhost.com/path')).toEqual(['section']);43 });44 it('Returns proper sections when glob pattern is used at the end.', function () {45 obj['Magento_Customer/js/section-config']({46 sections: {47 'path/*': [48 'section'49 ]50 },51 baseUrls: [52 'http://localhost.com/',53 'https://localhost.com/'54 ]55 });56 expect(obj.getAffectedSections('https://localhost.com/path/subpath')).toEqual(['section']);57 });58 it('Returns proper sections when glob pattern is used inside.', function () {59 obj['Magento_Customer/js/section-config']({60 sections: {61 '*/subpath': [62 'section'63 ]64 },65 baseUrls: [66 'http://localhost.com/',67 'https://localhost.com/'68 ]69 });70 expect(obj.getAffectedSections('https://localhost.com/path/subpath')).toEqual(['section']);71 });72 it('Strips "index.php" suffix from provided URL.', function () {73 obj['Magento_Customer/js/section-config']({74 sections: {75 'path': [76 'section'77 ]78 },79 baseUrls: [80 'http://localhost.com/'81 ]82 });83 expect(obj.getAffectedSections('http://localhost.com/path/index.php')).toEqual(['section']);84 });85 it('Adds sections for all URLs "*" to found ones.', function () {86 obj['Magento_Customer/js/section-config']({87 sections: {88 'path': [89 'section'90 ],91 '*': [92 'all'93 ]94 },95 baseUrls: [96 'http://localhost.com/'97 ]98 });99 expect(obj.getAffectedSections('http://localhost.com/path')).toEqual(['section', 'all']);100 });101 it('Returns "*" sections for all URLs.', function () {102 obj['Magento_Customer/js/section-config']({103 sections: {104 '*': [105 'all'106 ]107 },108 baseUrls: [109 'http://localhost.com/'110 ]111 });112 expect(obj.getAffectedSections('http://localhost.com/path')).toEqual(['all']);113 });114 it('Ignores capitalization in parts of URL.', function () {115 obj['Magento_Customer/js/section-config']({116 sections: {117 'path': [118 'section'119 ]120 },121 baseUrls: [122 'http://localhost.com/'123 ]124 });125 expect(obj.getAffectedSections('http://localhost.com/PaTh')).toEqual(['section']);126 });127 });128 describe('"filterClientSideSections" method', function () {129 it('Does not throw before component is initialized.', function () {130 expect(function () {131 obj.filterClientSideSections();132 }).not.toThrow();133 });134 it('Returns empty array when all sections are client side.', function () {135 var sections = ['test'];136 obj['Magento_Customer/js/section-config']({137 clientSideSections: sections138 });139 expect(obj.filterClientSideSections(sections)).toEqual([]);140 });141 it('Filters out client side sections.', function () {142 var allSections = ['test', 'client'],143 clientSections = ['client'];144 obj['Magento_Customer/js/section-config']({145 clientSideSections: clientSections146 });147 expect(obj.filterClientSideSections(allSections)).toEqual(['test']);148 });149 });150 describe('"isClientSideSection" method', function () {151 it('Does not throw before component is initialized.', function () {152 expect(function () {153 obj.isClientSideSection();154 }).not.toThrow();155 });156 it('Returns true if section is defined as client side.', function () {157 obj['Magento_Customer/js/section-config']({158 clientSideSections: ['client']159 });160 expect(obj.isClientSideSection('client')).toBe(true);161 });162 it('Returns false if section is not defined as client side.', function () {163 obj['Magento_Customer/js/section-config']({164 clientSideSections: ['client']165 });166 expect(obj.isClientSideSection('test')).toBe(false);167 });168 it('Returns false if section is not client side and sections are not defined.', function () {169 obj['Magento_Customer/js/section-config']({170 clientSideSections: []171 });172 expect(obj.isClientSideSection('test')).toBe(false);173 });174 });175 describe('"getSectionNames" method', function () {176 it('Does not throw before component is initialized.', function () {177 expect(function () {178 obj.getSectionNames();179 }).not.toThrow();180 });181 it('Returns defined section names.', function () {182 var sections = ['test'];183 obj['Magento_Customer/js/section-config']({184 sectionNames: sections185 });186 expect(obj.getSectionNames()).toBe(sections);187 });188 });189 });...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run fMBT automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful