mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
ldgen: additional tests for generation support classes
This commit is contained in:
parent
a41a56b5b0
commit
0142676cbf
@ -72,8 +72,10 @@ test_ldgen_on_host:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd tools/ldgen/test
|
||||
- ./test_fragments.py
|
||||
- ./test_generation.py
|
||||
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_fragments.py
|
||||
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_generation.py
|
||||
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_entity.py
|
||||
- ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_output_commands.py
|
||||
variables:
|
||||
LC_ALL: C.UTF-8
|
||||
|
||||
|
@ -88,8 +88,10 @@ tools/kconfig_new/test/confserver/test_confserver.py
|
||||
tools/kconfig_new/test/gen_kconfig_doc/test_kconfig_out.py
|
||||
tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py
|
||||
tools/ldgen/ldgen.py
|
||||
tools/ldgen/test/test_entity.py
|
||||
tools/ldgen/test/test_fragments.py
|
||||
tools/ldgen/test/test_generation.py
|
||||
tools/ldgen/test/test_output_commands.py
|
||||
tools/mass_mfg/mfg_gen.py
|
||||
tools/mkdfu.py
|
||||
tools/mkuf2.py
|
||||
|
78
tools/ldgen/output_commands.py
Normal file
78
tools/ldgen/output_commands.py
Normal file
@ -0,0 +1,78 @@
|
||||
#
|
||||
# Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
from entity import Entity
|
||||
|
||||
|
||||
class InputSectionDesc():
|
||||
|
||||
def __init__(self, entity, sections, exclusions=None):
|
||||
assert(entity.specificity != Entity.Specificity.SYMBOL)
|
||||
|
||||
self.entity = entity
|
||||
self.sections = set(sections)
|
||||
|
||||
self.exclusions = set()
|
||||
|
||||
if exclusions:
|
||||
assert(not [e for e in exclusions if e.specificity == Entity.Specificity.SYMBOL or
|
||||
e.specificity == Entity.Specificity.NONE])
|
||||
self.exclusions = set(exclusions)
|
||||
else:
|
||||
self.exclusions = set()
|
||||
|
||||
def __str__(self):
|
||||
if self.sections:
|
||||
exclusion_strings = []
|
||||
|
||||
for exc in sorted(self.exclusions):
|
||||
if exc.specificity == Entity.Specificity.ARCHIVE:
|
||||
exc_string = '*%s' % (exc.archive)
|
||||
else:
|
||||
exc_string = '*%s:%s.*' % (exc.archive, exc.obj)
|
||||
|
||||
exclusion_strings.append(exc_string)
|
||||
|
||||
section_strings = []
|
||||
|
||||
if exclusion_strings:
|
||||
exclusion_string = 'EXCLUDE_FILE(%s)' % ' '.join(exclusion_strings)
|
||||
|
||||
for section in sorted(self.sections):
|
||||
section_strings.append('%s %s' % (exclusion_string, section))
|
||||
else:
|
||||
for section in sorted(self.sections):
|
||||
section_strings.append(section)
|
||||
|
||||
sections_string = '(%s)' % ' '.join(section_strings)
|
||||
else:
|
||||
sections_string = '( )'
|
||||
|
||||
command = None
|
||||
|
||||
if self.entity.specificity == Entity.Specificity.NONE:
|
||||
command = '*%s' % (sections_string)
|
||||
elif self.entity.specificity == Entity.Specificity.ARCHIVE:
|
||||
command = '*%s:%s' % (self.entity.archive, sections_string)
|
||||
else:
|
||||
command = '*%s:%s.*%s' % (self.entity.archive, self.entity.obj, sections_string)
|
||||
|
||||
return command
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.entity == other.entity and
|
||||
self.sections == other.sections and
|
||||
self.exclusions == other.exclusions)
|
@ -343,6 +343,111 @@ Idx Name Size VMA LMA File off Algn
|
||||
49 .xt.prop 00000408 00000000 00000000 00002f3e 2**0
|
||||
CONTENTS, RELOC, READONLY
|
||||
|
||||
port.cpp.obj: file format elf32-xtensa-le
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
0 .literal.pxPortInitialiseStack 00000018 00000000 00000000 00000034 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
1 .literal.xPortStartScheduler 00000014 00000000 00000000 0000004c 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
2 .literal.xPortSysTickHandler 00000008 00000000 00000000 00000060 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
3 .literal.vPortYieldOtherCore 00000004 00000000 00000000 00000068 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
4 .literal.vPortReleaseTaskMPUSettings 00000004 00000000 00000000 0000006c 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
5 .literal.xPortInIsrContext 00000008 00000000 00000000 00000070 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
6 .iram1.literal 00000004 00000000 00000000 00000078 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
7 .literal.vPortAssertIfInISR 00000018 00000000 00000000 0000007c 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
8 .literal.vPortCPUInitializeMutex 00000004 00000000 00000000 00000094 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
9 .literal.vPortCPUAcquireMutex 00000030 00000000 00000000 00000098 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
10 .literal.vPortCPUAcquireMutexTimeout 00000030 00000000 00000000 000000c8 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
11 .literal.vPortCPUReleaseMutex 00000028 00000000 00000000 000000f8 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
12 .literal.vPortSetStackWatchpoint 00000008 00000000 00000000 00000120 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
13 .text 00000000 00000000 00000000 00000128 2**0
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
14 .data 00000000 00000000 00000000 00000128 2**0
|
||||
CONTENTS, ALLOC, LOAD, DATA
|
||||
15 .bss 00000000 00000000 00000000 00000128 2**0
|
||||
ALLOC
|
||||
16 .text.pxPortInitialiseStack 00000086 00000000 00000000 00000128 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
17 .text.vPortEndScheduler 00000005 00000000 00000000 000001b0 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
18 .text.xPortStartScheduler 0000002e 00000000 00000000 000001b8 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
19 .text.xPortSysTickHandler 00000016 00000000 00000000 000001e8 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
20 .text.vPortYieldOtherCore 0000000e 00000000 00000000 00000200 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
21 .text.vPortStoreTaskMPUSettings 00000013 00000000 00000000 00000210 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
22 .text.vPortReleaseTaskMPUSettings 0000000e 00000000 00000000 00000224 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
23 .text.xPortInIsrContext 00000026 00000000 00000000 00000234 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
24 .iram1 0000001a 00000000 00000000 0000025c 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
25 .rodata.str1.4 0000013b 00000000 00000000 00000278 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
||||
26 .text.vPortAssertIfInISR 00000025 00000000 00000000 000003b4 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
27 .text.vPortCPUInitializeMutex 0000000e 00000000 00000000 000003dc 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
28 .text.vPortCPUAcquireMutex 00000088 00000000 00000000 000003ec 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
29 .text.vPortCPUAcquireMutexTimeout 000000ab 00000000 00000000 00000474 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
30 .text.vPortCPUReleaseMutex 00000061 00000000 00000000 00000520 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
31 .text.vPortSetStackWatchpoint 0000001a 00000000 00000000 00000584 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
32 .text.xPortGetTickRateHz 00000008 00000000 00000000 000005a0 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
33 .rodata.__func__$5264 00000029 00000000 00000000 000005a8 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
||||
34 .rodata.__func__$5259 00000029 00000000 00000000 000005d4 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
||||
35 .rodata.__FUNCTION__$5243 00000013 00000000 00000000 00000600 2**2
|
||||
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
||||
36 .bss.port_interruptNesting 00000008 00000000 00000000 00000614 2**2
|
||||
ALLOC
|
||||
37 .bss.port_xSchedulerRunning 00000008 00000000 00000000 00000614 2**2
|
||||
ALLOC
|
||||
38 .debug_frame 00000190 00000000 00000000 00000614 2**2
|
||||
CONTENTS, RELOC, READONLY, DEBUGGING
|
||||
39 .debug_info 00000e78 00000000 00000000 000007a4 2**0
|
||||
CONTENTS, RELOC, READONLY, DEBUGGING
|
||||
40 .debug_abbrev 00000404 00000000 00000000 0000161c 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
41 .debug_loc 000005f1 00000000 00000000 00001a20 2**0
|
||||
CONTENTS, RELOC, READONLY, DEBUGGING
|
||||
42 .debug_aranges 00000098 00000000 00000000 00002011 2**0
|
||||
CONTENTS, RELOC, READONLY, DEBUGGING
|
||||
43 .debug_ranges 000000a0 00000000 00000000 000020a9 2**0
|
||||
CONTENTS, RELOC, READONLY, DEBUGGING
|
||||
44 .debug_line 000005fb 00000000 00000000 00002149 2**0
|
||||
CONTENTS, RELOC, READONLY, DEBUGGING
|
||||
45 .debug_str 0000071f 00000000 00000000 00002744 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
46 .comment 0000003b 00000000 00000000 00002e63 2**0
|
||||
CONTENTS, READONLY
|
||||
47 .xtensa.info 00000038 00000000 00000000 00002e9e 2**0
|
||||
CONTENTS, READONLY
|
||||
48 .xt.lit 00000068 00000000 00000000 00002ed6 2**0
|
||||
CONTENTS, RELOC, READONLY
|
||||
49 .xt.prop 00000408 00000000 00000000 00002f3e 2**0
|
||||
CONTENTS, RELOC, READONLY
|
||||
|
||||
portasm.S.obj: file format elf32-xtensa-le
|
||||
|
||||
Sections:
|
39
tools/ldgen/test/data/test_entity/libfreertos.a.txt
Normal file
39
tools/ldgen/test/data/test_entity/libfreertos.a.txt
Normal file
@ -0,0 +1,39 @@
|
||||
In archive /home/user/build/esp-idf/freertos/libfreertos.a:
|
||||
|
||||
croutine.c.obj: file format elf32-xtensa-le
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
0 .literal.prvCheckPendingReadyList 00000018 00000000 00000000 00000034 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
1 .literal.prvCheckDelayedList 0000002c 00000000 00000000 0000004c 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
|
||||
croutine.cpp.obj: file format elf32-xtensa-le
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
9 .text.prvCheckPendingReadyList 00000056 00000000 00000000 000000d8 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
10 .text.prvCheckDelayedList 000000ac 00000000 00000000 00000130 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
|
||||
croutine.S.obj: file format elf32-xtensa-le
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
26 .debug_frame 000000a0 00000000 00000000 00000394 2**2
|
||||
CONTENTS, RELOC, READONLY, DEBUGGING
|
||||
27 .debug_info 000006b8 00000000 00000000 00000434 2**0
|
||||
CONTENTS, RELOC, READONLY, DEBUGGING
|
||||
28 .debug_abbrev 00000233 00000000 00000000 00000aec 2**0
|
||||
CONTENTS, READONLY, DEBUGGING
|
||||
|
||||
timers.o: file format elf32-xtensa-le
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
0 .literal.prvGetNextExpireTime 00000004 00000000 00000000 00000034 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
||||
1 .literal.prvInsertTimerInActiveList 00000010 00000000 00000000 00000038 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
@ -1,4 +1,4 @@
|
||||
In archive /home/user/ãóç+ěščřžýáíé/build/esp-idf/freertos/libsections_parse.a:
|
||||
In archive /home/user/ãóç+ěščřžýáíé/build/esp-idf/freertos/ěščřžýáíé.a:
|
||||
|
||||
croutine.c.obj: file format elf32-littleriscv
|
||||
|
||||
@ -11,9 +11,9 @@ Idx Name Size VMA LMA File off Algn
|
||||
2 .bss 00000000 00000000 00000000 00000034 2**0
|
||||
ALLOC
|
||||
|
||||
FreeRTOS-openocd.c.obj: file format elf32-xtensa-le // 'F' should not get included in match for 'CONTENTS, ALLOC, LOAD ...' prior
|
||||
FreeRTOS-ěščřžýáíé.c.obj: file format elf32-xtensa-le // 'F' should not get included in match for 'CONTENTS, ALLOC, LOAD ...' prior
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
0 .literal.prvCheckPendingReadyList 00000018 00000000 00000000 00000034 2**2
|
||||
0 .literal.ěščřžýáíé 00000018 00000000 00000000 00000034 2**2
|
||||
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
|
251
tools/ldgen/test/test_entity.py
Executable file
251
tools/ldgen/test/test_entity.py
Executable file
@ -0,0 +1,251 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright 2018-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from entity import Entity, EntityDB
|
||||
except ImportError:
|
||||
sys.path.append('../')
|
||||
from entity import Entity, EntityDB
|
||||
|
||||
|
||||
class EntityTest(unittest.TestCase):
|
||||
|
||||
def test_create_none(self):
|
||||
entity = Entity(Entity.ALL)
|
||||
self.assertEqual(Entity.Specificity.NONE, entity.specificity)
|
||||
|
||||
entity = Entity(None)
|
||||
self.assertEqual(Entity.Specificity.NONE, entity.specificity)
|
||||
|
||||
entity = Entity()
|
||||
self.assertEqual(Entity.Specificity.NONE, entity.specificity)
|
||||
|
||||
def test_create_archive(self):
|
||||
entity = Entity('libfreertos.a')
|
||||
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
|
||||
|
||||
entity = Entity('libfreertos.a', Entity.ALL, Entity.ALL)
|
||||
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
|
||||
|
||||
entity = Entity('libfreertos.a', None, None)
|
||||
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
|
||||
|
||||
entity = Entity('libfreertos.a', Entity.ALL, None)
|
||||
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
|
||||
|
||||
entity = Entity('libfreertos.a', None, Entity.ALL)
|
||||
self.assertEqual(Entity.Specificity.ARCHIVE, entity.specificity)
|
||||
|
||||
def test_create_obj(self):
|
||||
entity = Entity('libfreertos.a', 'croutine')
|
||||
self.assertEqual(Entity.Specificity.OBJ, entity.specificity)
|
||||
|
||||
entity = Entity('libfreertos.a', 'croutine', Entity.ALL)
|
||||
self.assertEqual(Entity.Specificity.OBJ, entity.specificity)
|
||||
|
||||
entity = Entity('libfreertos.a', 'croutine', None)
|
||||
self.assertEqual(Entity.Specificity.OBJ, entity.specificity)
|
||||
|
||||
def test_create_symbol(self):
|
||||
entity = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
|
||||
self.assertEqual(Entity.Specificity.SYMBOL, entity.specificity)
|
||||
|
||||
def test_create_invalid(self):
|
||||
with self.assertRaises(ValueError):
|
||||
Entity(None, 'croutine')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Entity(Entity.ALL, 'croutine')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Entity(None, None, 'prvCheckPendingReadyList')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Entity(Entity.ALL, Entity.ALL, 'prvCheckPendingReadyList')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Entity(None, Entity.ALL, 'prvCheckPendingReadyList')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Entity(Entity.ALL, None, 'prvCheckPendingReadyList')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Entity('libfreertos.a', None, 'prvCheckPendingReadyList')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Entity('libfreertos.a', Entity.ALL, 'prvCheckPendingReadyList')
|
||||
|
||||
def test_compare_different_specificity(self):
|
||||
# Different specificity: NONE < ARCHIVE < OBJ < SYMBOL
|
||||
entity_a = Entity()
|
||||
entity_b = Entity('libfreertos.a')
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a')
|
||||
entity_b = Entity('libfreertos.a', 'croutine')
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a', 'croutine')
|
||||
entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity(Entity.ALL)
|
||||
entity_b = Entity('libfreertos.a')
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a', Entity.ALL)
|
||||
entity_b = Entity('libfreertos.a', 'croutine')
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a', 'croutine', Entity.ALL)
|
||||
entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
def test_compare_equal(self):
|
||||
# Compare equal specificities and members
|
||||
entity_a = Entity()
|
||||
entity_b = Entity()
|
||||
self.assertEqual(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a')
|
||||
entity_b = Entity('libfreertos.a')
|
||||
self.assertEqual(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a', 'croutine')
|
||||
entity_b = Entity('libfreertos.a', 'croutine')
|
||||
self.assertEqual(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
|
||||
entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')
|
||||
self.assertEqual(entity_a, entity_b)
|
||||
|
||||
def test_compare_none_vs_all(self):
|
||||
# Two entities might have the same specifity whether
|
||||
# Entity.ALL is used or not specified; the latter is
|
||||
# considered less than the former.
|
||||
entity_a = Entity()
|
||||
entity_b = Entity(Entity.ALL)
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a')
|
||||
entity_b = Entity('libfreertos.a', Entity.ALL, Entity.ALL)
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a', 'croutine')
|
||||
entity_b = Entity('libfreertos.a', 'croutine', Entity.ALL)
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
def test_compare_same_specificity(self):
|
||||
# Test that entities will be compared alphabetically
|
||||
# when the specificities are the same.
|
||||
entity_a = Entity('libfreertos_a.a')
|
||||
entity_b = Entity('libfreertos_b.a')
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos_b.a', 'croutine_a')
|
||||
entity_b = Entity('libfreertos_a.a', 'croutine_b')
|
||||
self.assertLess(entity_b, entity_a)
|
||||
|
||||
entity_a = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList_a')
|
||||
entity_b = Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList_b')
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a', 'croutine_b', 'prvCheckPendingReadyList_a')
|
||||
entity_b = Entity('libfreertos.a', 'croutine_a', 'prvCheckPendingReadyList_b')
|
||||
self.assertLess(entity_b, entity_a)
|
||||
|
||||
entity_a = Entity('libfreertos_a.a', 'croutine_b', 'prvCheckPendingReadyList_a')
|
||||
entity_b = Entity('libfreertos_b.a', 'croutine_a', 'prvCheckPendingReadyList_b')
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
def test_compare_all_non_character(self):
|
||||
# Test that Entity.ALL is not treated as an
|
||||
# ordinary character in comparisons.
|
||||
entity_a = Entity(Entity.ALL)
|
||||
entity_b = Entity(chr(ord(Entity.ALL[0]) - 1))
|
||||
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a', Entity.ALL)
|
||||
entity_b = Entity('libfreertos.a', chr(ord(Entity.ALL[0]) - 1))
|
||||
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
entity_a = Entity('libfreertos.a', 'croutine', '*')
|
||||
entity_b = Entity('libfreertos.a', 'croutine', chr(ord(Entity.ALL[0]) - 1))
|
||||
|
||||
self.assertLess(entity_a, entity_b)
|
||||
|
||||
|
||||
class EntityDBTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.entities = EntityDB()
|
||||
|
||||
with open('data/test_entity/libfreertos.a.txt') as objdump:
|
||||
self.entities.add_sections_info(objdump)
|
||||
|
||||
def test_get_archives(self):
|
||||
archives = self.entities.get_archives()
|
||||
self.assertEqual(set(archives), set(['libfreertos.a']))
|
||||
|
||||
def test_get_objs(self):
|
||||
objs = self.entities.get_objects('libfreertos.a')
|
||||
self.assertEqual(set(objs), set(['croutine.S.obj', 'croutine.c.obj', 'croutine.cpp.obj', 'timers.o']))
|
||||
|
||||
def test_get_sections(self):
|
||||
# Needs disambugation between possible matches: croutine.S, croutine.c, croutine.cpp
|
||||
with self.assertRaises(ValueError):
|
||||
self.entities.get_sections('libfreertos.a', 'croutine')
|
||||
|
||||
# Test disambugation works
|
||||
sections = self.entities.get_sections('libfreertos.a', 'croutine.c')
|
||||
expected = set(['.literal.prvCheckPendingReadyList', '.literal.prvCheckDelayedList'])
|
||||
self.assertEqual(set(sections), expected)
|
||||
|
||||
sections = self.entities.get_sections('libfreertos.a', 'croutine.S')
|
||||
expected = set(['.debug_frame', '.debug_info', '.debug_abbrev'])
|
||||
self.assertEqual(set(sections), expected)
|
||||
|
||||
# Test .o extension works
|
||||
sections = self.entities.get_sections('libfreertos.a', 'timers')
|
||||
expected = set(['.literal.prvGetNextExpireTime', '.literal.prvInsertTimerInActiveList'])
|
||||
self.assertEqual(set(sections), expected)
|
||||
|
||||
def test_parsing(self):
|
||||
# Tests parsing objdump with the following:
|
||||
#
|
||||
# - non-ascii characters
|
||||
# - different architecture string
|
||||
# - different column entries for each sections
|
||||
# - unexpected 'comments'
|
||||
with open('data/test_entity/parse_test.txt') as objdump:
|
||||
self.entities.add_sections_info(objdump)
|
||||
|
||||
sections = self.entities.get_sections('ěščřžýáíé.a', 'croutine')
|
||||
self.assertEqual(set(sections), set(['.text', '.data', '.bss']))
|
||||
|
||||
sections = self.entities.get_sections('ěščřžýáíé.a', 'FreeRTOS-ěščřžýáíé')
|
||||
self.assertEqual(set(sections), set(['.literal.ěščřžýáíé']))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
141
tools/ldgen/test/test_output_commands.py
Executable file
141
tools/ldgen/test/test_output_commands.py
Executable file
@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from output_commands import InputSectionDesc
|
||||
except ImportError:
|
||||
sys.path.append('../')
|
||||
from output_commands import InputSectionDesc
|
||||
|
||||
from entity import Entity
|
||||
|
||||
SECTIONS = ['.text', '.text.*', '.literal', '.literal.*']
|
||||
|
||||
FREERTOS = Entity('libfreertos.a')
|
||||
CROUTINE = Entity('libfreertos.a', 'croutine')
|
||||
|
||||
|
||||
class InputSectionDescTest(unittest.TestCase):
|
||||
|
||||
def test_output_00(self):
|
||||
# Test default (catch-all) command
|
||||
expected = '*(.literal .literal.* .text .text.*)'
|
||||
|
||||
desc = InputSectionDesc(Entity(), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
desc = InputSectionDesc(Entity(Entity.ALL), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
def test_output_01(self):
|
||||
# Test library placement command
|
||||
expected = '*libfreertos.a:(.literal .literal.* .text .text.*)'
|
||||
|
||||
desc = InputSectionDesc(Entity('libfreertos.a'), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
desc = InputSectionDesc(Entity('libfreertos.a', Entity.ALL), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
desc = InputSectionDesc(Entity('libfreertos.a', None, Entity.ALL), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
desc = InputSectionDesc(Entity('libfreertos.a', Entity.ALL, Entity.ALL), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
def test_output_02(self):
|
||||
# Test object placement command
|
||||
expected = '*libfreertos.a:croutine.*(.literal .literal.* .text .text.*)'
|
||||
|
||||
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine', Entity.ALL), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
# Disambugated placement
|
||||
expected = '*libfreertos.a:croutine.c.*(.literal .literal.* .text .text.*)'
|
||||
|
||||
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine.c'), SECTIONS)
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
def test_output_03(self):
|
||||
# Invalid entity specification
|
||||
with self.assertRaises(AssertionError):
|
||||
InputSectionDesc(Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList'), SECTIONS)
|
||||
|
||||
with self.assertRaises(AssertionError):
|
||||
InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS, [Entity()])
|
||||
|
||||
with self.assertRaises(AssertionError):
|
||||
InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS, [Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')])
|
||||
|
||||
def test_output_04(self):
|
||||
# Test exclusions
|
||||
|
||||
# Library
|
||||
expected = ('*libfreertos.a:croutine.*'
|
||||
'(EXCLUDE_FILE(*libfreertos.a) '
|
||||
'.literal EXCLUDE_FILE(*libfreertos.a) '
|
||||
'.literal.* EXCLUDE_FILE(*libfreertos.a) '
|
||||
'.text EXCLUDE_FILE(*libfreertos.a) .text.*)')
|
||||
desc = InputSectionDesc(CROUTINE, SECTIONS, [FREERTOS])
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
# Object
|
||||
expected = ('*libfreertos.a:croutine.*'
|
||||
'(EXCLUDE_FILE(*libfreertos.a:croutine.*) '
|
||||
'.literal EXCLUDE_FILE(*libfreertos.a:croutine.*) '
|
||||
'.literal.* EXCLUDE_FILE(*libfreertos.a:croutine.*) '
|
||||
'.text EXCLUDE_FILE(*libfreertos.a:croutine.*) .text.*)')
|
||||
desc = InputSectionDesc(CROUTINE, SECTIONS, [CROUTINE])
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
# Multiple exclusions
|
||||
expected = ('*libfreertos.a:croutine.*'
|
||||
'(EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) '
|
||||
'.literal EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) '
|
||||
'.literal.* EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) '
|
||||
'.text EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) .text.*)')
|
||||
desc = InputSectionDesc(CROUTINE, SECTIONS, [FREERTOS, CROUTINE])
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
# Disambugated exclusion
|
||||
expected = ('*libfreertos.a:croutine.*'
|
||||
'(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) '
|
||||
'.literal EXCLUDE_FILE(*libfreertos.a:croutine.c.*) '
|
||||
'.literal.* EXCLUDE_FILE(*libfreertos.a:croutine.c.*) '
|
||||
'.text EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)')
|
||||
desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')])
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
def test_output_05(self):
|
||||
# Test empty sections
|
||||
expected = '*libfreertos.a:croutine.*( )'
|
||||
|
||||
desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), [])
|
||||
self.assertEqual(expected, str(desc))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in New Issue
Block a user