Шаманъ 1 15 мая, 2017 Опубликовано 15 мая, 2017 · Жалоба а в качестве эксперемента можете подсунуть "руками" memset/memcpy/memmove? чтоб результат погдядеть... Подсунул, это не сложно - там всего три функции. Результата не вышло - улетает сразу в hardfault. По всему он скомпилировал какую-то полную хрень в memset: Из-за чего начинается рекурсивный вызов ее, выход стека за границы ОЗУ и hardfault. Собственно до main не доходит, можете поэкспериментировать - вот код, memmove и memset стандартные из исходников libgcc: void Reset_Handler(void) { /* Initialize data */ memmove(&_data_start, &_data_start_flash, &_data_end - &_data_start); /* Initialize settings with default values */ memmove(&_settings_start, &_settings_start_flash, &_settings_end - &_settings_start); /* Initialize service with default values */ memmove(&_service_start, &_service_start_flash, &_service_end - &_service_start); /* Initialize nvram with default values */ memmove(&_nvram_start, &_nvram_start_flash, &_nvram_end - &_nvram_start); /* Initialize bss */ memset(&_bss_start, 0, &_bss_end - &_bss_start); /* Zero fill sram1/sram2*/ memset(&_sram1_start, 0, &_sram1_end - &_sram1_start); memset(&_sram2_start, 0, &_sram2_end - &_sram2_start); /* Call the application's entry point.*/ main(); } я к счастью ничем внешним не пользуюсь, даже libc и libm свои "местные" в исхниках, в связи с чем никакие либы кроме libgcc самого компиллера в проект не линкуются Я использую только memmove, memcpy и memset. И они есть в libgcc, если мне память не изменяет. Все остальное, кроме FatFS, тоже свое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 16 мая, 2017 Опубликовано 16 мая, 2017 · Жалоба 2_Шаманъ все это подозрительно... проверил у себя - в libgcc нет этих функций в libgcc. klen@ubuntu:/opt/arm-kgp-eabi-8/lib/gcc/arm-kgp-eabi/8.0.0$ arm-kgp-eabi-objdump libgcc.a -t | grep memset 00000000 *UND* 00000000 memset klen@ubuntu:/opt/arm-kgp-eabi-8/lib/gcc/arm-kgp-eabi/8.0.0$ arm-kgp-eabi-objdump libgcc.a -t | grep memmov klen@ubuntu:/opt/arm-kgp-eabi-8/lib/gcc/arm-kgp-eabi/8.0.0$ arm-kgp-eabi-objdump libgcc.a -t | grep memcpy 00000000 *UND* 00000000 memcpy 00000000 *UND* 00000000 memcpy klen@ubuntu:/opt/arm-kgp-eabi-8/lib/gcc/arm-kgp-eabi/8.0.0$ они внешние.. у меня работает, у Вас нет - а где разница, вот в чем вопрос.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 1 17 мая, 2017 Опубликовано 17 мая, 2017 (изменено) · Жалоба проверил у себя - в libgcc нет этих функций в libgcc. ну я просто из исходников libgcc.a от 6.3.1 закинул себе в проект все три функции, потому предположил, что они там должны быть. у меня работает, у Вас нет - а где разница, вот в чем вопрос.. Вы видели код memset? Как Вы думаете это похоже на нормальный код? Вот исходник memset (взят из исходников libgcc.a от 6.3.1, но это никакого значения не имеет), что сгенерировал GCC 8.0.0 Вы можете посмотреть выше: /* Public domain. */ #include <stddef.h> void * memset (void *dest, int val, size_t len) { unsigned char *ptr = dest; while (len-- > 0) *ptr++ = val; return dest; } У меня тоже работает все, причем под любой версией "штатного" GCC. Могу еще попробовать собрать 8.0.0, но без -flto. все это подозрительно... Скомпилировал проект без -flto, и что Вы думаете...вот, так с точки зрения GCC 8.0.0 должны выглядеть функция memse (исходник см. выше), та же беда, что и с -flto: 2:memset.c **** #include <stddef.h> 3:memset.c **** 4:memset.c **** void * 5:memset.c **** memset (void *dest, int val, size_t len) 6:memset.c **** { 28 .loc 1 6 0 29 .cfi_startproc 30 @ args = 0, pretend = 0, frame = 0 31 @ frame_needed = 0, uses_anonymous_args = 0 32 .LVL0: 33 0000 10B5 push {r4, lr} 34 .cfi_def_cfa_offset 8 35 .cfi_offset 4, -8 36 .cfi_offset 14, -4 37 .loc 1 6 0 38 0002 0446 mov r4, r0 39 .LVL1: 7:memset.c **** unsigned char *ptr = dest; 8:memset.c **** while (len-- > 0) 40 .loc 1 8 0 41 0004 12B1 cbz r2, .L4 42 0006 C9B2 uxtb r1, r1 43 .LVL2: 44 0008 FFF7FEFF bl memset 45 .LVL3: 46 .L4: 9:memset.c **** *ptr++ = val; 10:memset.c **** return dest; 11:memset.c **** } 47 .loc 1 11 0 48 000c 2046 mov r0, r4 49 000e 10BD pop {r4, pc} 50 .cfi_endproc 51 .LFE0: 52 .size memset, .-memset klen, tсть какие-нибудь соображения? Изменено 17 мая, 2017 пользователем Шаманъ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 17 мая, 2017 Опубликовано 17 мая, 2017 · Жалоба ...... 47 .loc 1 11 0 48 000c 2046 mov r0, r4 49 000e 10BD pop {r4, pc} 50 .cfi_endproc ..... прикольнинько! он тупо врапер вставил :) халявщик! кода memset мы так и не увидели идей море, будем их исключать. такое поведение как мне кажется абсалютно нормально - мы где то не нормально что то объяснили компиллеру в коде! всегда так бывает. пока природа косяка не ясна но мы ее исследуем. шаг номер нуль. я компиляю либу со всеми mem* функциями и Вы пробуете ее линкануть - смотрим реакцию системы, далее следующий шаг. моя гипотеза - уши вылезут в итоге из заголовочных файлов - я думаю компилятор видит код тупо выполняет приказ заменить заглушкой, задача найти это место. в атаче libklibc.a - моя реализация libc, совместимая с хидерами от newlib. ничего не меняя нужно его добавить для линковки. в частности там внутри реализации 00000000 g F .text.memcpy 000001b0 memcpy 00000000 g F .text.memccpy 00000136 memccpy 00000000 g F .text.memchr 000000f6 memchr 00000000 g F .text.memset 00000068 memset 00000000 g F .text.memcmp 000000e6 memcmp 00000000 g F .text.memmove 00000270 memmove 00000000 g F .text.strlen 00000016 strlen 00000000 g F .text.strncpy 0000011a strncpy 00000000 g F .text.strcpy 00000010 strcpy 00000000 g F .text.strcmp 00000020 strcmp 00000000 g F .text.strncmp 0000003a strncmp 00000000 g F .text.strchr 00000022 strchr 00000000 g F .text.strspn 00000034 strspn 00000000 g F .text.strpbrk 0000002c strpbrk 00000000 g F .text.strcoll 00000020 strcoll 00000000 g F .text.strstr 00000042 strstr 00000000 g F .text.strcat 00000028 strcat 00000000 g F .text.strlcat 000001f0 strlcat 00000000 g F .text.strcspn 00000034 strcspn 00000000 g F .text.strerror 00000004 strerror 00000000 g F .text.strncat 00000110 strncat 00000000 g F .text.strtok 00000070 strtok 00000000 *UND* 00000000 reentrant 00000000 g F .text.strxfrm 00000172 strxfrm 00000000 g F .text.strrchr 00000022 strrchr 00000000 w F .text.strrchr 00000022 rindex . собрано с ключами : -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Ofast -fomit-frame-pointer -finline-functions -ffunction-sections -fdata-sections -fgraphite -funroll-loops -flto=8 -ffat-lto-objects -ggdb3 -fverbose-asm должно линковатся без проблем с LTO и без него если у Вас не-cotex-m4 приложу другую версию. libklibc.a.tar.7z Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 1 17 мая, 2017 Опубликовано 17 мая, 2017 · Жалоба прикольнинько! он тупо заглушку вставил :) халявщик! идей море, будем их исключать. Не, там похоже все печальнее, ибо кроме "заглушки" есть еще остатки цикла и, главное, рекурсия. Что никак нормальным быть не может: .LVL0: 33 0000 10B5 push {r4, lr} 38 0002 0446 mov r4, r0 41 0004 12B1 cbz r2, .L4 42 0006 C9B2 uxtb r1, r1 44 0008 FFF7FEFF bl memset 46 .L4: 48 000c 2046 mov r0, r4 49 000e 10BD pop {r4, pc} шаг номер нуль. я компиляю либу со всеми mem* функциями и Вы пробуете ее линкануть - смотрим реакцию системы, далее следующий шаг. моя гипотеза - уши вылезут в итоге из заголовочных файлов - я думаю компилятор видит код тупо выполняет приказ заменить заглушкой, задача найти это место. Не вопрос, но у меня cortex-m7 (stm32f746). Да, memmove, memset и memcpy достаточно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 17 мая, 2017 Опубликовано 17 мая, 2017 · Жалоба 2_Шаманъ >Не, там похоже все печальнее, ибо кроме "заглушки" есть еще остатки цикла и, главное, рекурсия. Что никак нормальным быть не может: есть мнение что эта рекурсия или "всегда" или "никогда", то есть тривиальный неправильный код >Не вопрос, но у меня cortex-m7 (stm32f746). Да, memmove, memset и memcpy достаточно. во первых бинарно m4-код по определению подходит к m7 ибо набор инструкций первого есть подмножество второго набора. во вторых... но может линкер не пропустить по "политическим" соображениям :) в ELF заголовке объектников есть флаги архитектуры которые линкер проверяет и решает "да" или "нет" поэтому версия для m7 : в результате вызваться должен код: Дизассемблирование раздела .text.memset: 00000000 <memset>: 0: b3c2 cbz r2, 74 <memset+0x74> 2: b2c9 uxtb r1, r1 4: 4603 mov r3, r0 6: b410 push {r4} 8: 1884 adds r4, r0, r2 a: f012 0207 ands.w r2, r2, #7 e: d019 beq.n 44 <memset+0x44> 10: 2a01 cmp r2, #1 12: d013 beq.n 3c <memset+0x3c> 14: 2a02 cmp r2, #2 16: d00f beq.n 38 <memset+0x38> 18: 2a03 cmp r2, #3 1a: d00b beq.n 34 <memset+0x34> 1c: 2a04 cmp r2, #4 1e: d007 beq.n 30 <memset+0x30> 20: 2a05 cmp r2, #5 22: d003 beq.n 2c <memset+0x2c> 24: 2a06 cmp r2, #6 26: d122 bne.n 6e <memset+0x6e> 28: 7019 strb r1, [r3, #0] 2a: 3301 adds r3, #1 2c: 7019 strb r1, [r3, #0] 2e: 3301 adds r3, #1 30: 7019 strb r1, [r3, #0] 32: 3301 adds r3, #1 34: 7019 strb r1, [r3, #0] 36: 3301 adds r3, #1 38: 7019 strb r1, [r3, #0] 3a: 3301 adds r3, #1 3c: 7019 strb r1, [r3, #0] 3e: 3301 adds r3, #1 40: 42a3 cmp r3, r4 42: d011 beq.n 68 <memset+0x68> 44: 7019 strb r1, [r3, #0] 46: 3308 adds r3, #8 48: f803 1c07 strb.w r1, [r3, #-7] 4c: f803 1c06 strb.w r1, [r3, #-6] 50: f803 1c05 strb.w r1, [r3, #-5] 54: f803 1c04 strb.w r1, [r3, #-4] 58: f803 1c03 strb.w r1, [r3, #-3] 5c: f803 1c02 strb.w r1, [r3, #-2] 60: f803 1c01 strb.w r1, [r3, #-1] 64: 42a3 cmp r3, r4 66: d1ed bne.n 44 <memset+0x44> 68: f85d 4b04 ldr.w r4, [sp], #4 6c: 4770 bx lr 6e: 1c43 adds r3, r0, #1 70: 7001 strb r1, [r0, #0] 72: e7d9 b.n 28 <memset+0x28> 74: 4770 bx lr 76: bf00 nop просьба не пугатся на длинну кода :) это "оптимальный" по скорости код в версии критерия -Ofast оптимальноси GCC 8.0.0 c участием графита - тоесть циклы разверныты в максимум чтоб с экономить скорость на переходах. соответственно размер какой угодно и флеш не экономится - принимается что пирог из жирафа длинный и поэтому риса в него напихать можно столько сколько хочется! для сравнения все тоже самое но с -Os Дизассемблирование раздела .text.memset: 00000000 <memset>: 0: 4402 add r2, r0 2: 4603 mov r3, r0 4: b2c9 uxtb r1, r1 6: 4293 cmp r3, r2 8: d100 bne.n c <memset+0xc> a: 4770 bx lr c: 7019 strb r1, [r3, #0] e: 3301 adds r3, #1 10: e7f9 b.n 6 <memset+0x6> что быстрее первое или второе большой вопрос, поскольку это зависит от "окружающего вызывающего кода", оптимизатор, в частности LTO-фаза, в итоге все сваливает в общий котел и что на выходе получится заранее трудно предсказуемо. у меня обычно -Ofast немного быстрее а -Os всегда много меньше. другие оптимизации проигрывают практически всегда и во всем. libklibc_m7.a.tar.7z Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 1 17 мая, 2017 Опубликовано 17 мая, 2017 · Жалоба есть мнение что эта рекурсия или "всегда" или "никогда", то есть тривиальный неправильный код Рекурсия там есть - именно из-за нее в HardFault выпадает программа. Что неправильно - тут и обсуждать особенно нечего. во вторых... С этой версией без -flto запустилось. Загрузка процессора в среднем больше на 2%, чем на 6.3.1, код больше на 6кБ. Сейчас с -flto соберу посмотрю. Мда... с -flto полная лажа - загрузка процессора больше в 2.5раза. Картина такая же, как на 6.3.1 при включении -flto и -ggdb3 :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 17 мая, 2017 Опубликовано 17 мая, 2017 · Жалоба Рекурсия там есть - именно из-за нее в HardFault выпадает программа. Что неправильно - тут и обсуждать особенно нечего. С этой версией без -flto запустилось. Загрузка процессора в среднем больше на 2%, чем на 6.3.1, код больше на 6кБ. Сейчас с -flto соберу посмотрю. Мда... с -flto полная лажа - загрузка процессора больше в 2.5раза. Картина такая же, как на 6.3.1 при включении -flto и -ggdb3 :( ничего страшного, .. шорты превращаются... превращаются... извините, мелкие технические неполадки наверно по смыслу мне нужно собрать два релизных 6.3 и 7.1 - для сравнения c "конкурентами" нужно? и все таки меня терзают смутные сомнения.. к следующему разу сделаю сборку по иному и попробуем еще эксперимент .... сомнения.. все ли мы правильно делаем? .... правильно ли мы интерпретируем увиденное .... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 1 18 мая, 2017 Опубликовано 18 мая, 2017 · Жалоба наверно по смыслу мне нужно собрать два релизных 6.3 и 7.1 - для сравнения c "конкурентами" нужно? А в чем смысл? В середине июня обещали вроде обновление "конкурентов" до 7 версии GCC. и все таки меня терзают смутные сомнения.. к следующему разу сделаю сборку по иному и попробуем еще эксперимент .... сомнения.. все ли мы правильно делаем? .... правильно ли мы интерпретируем увиденное .... А как еще можно интерпретировать проблему с генерацией кода и показания загрузки процессора? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 19 мая, 2017 Опубликовано 19 мая, 2017 · Жалоба А как еще можно интерпретировать проблему с генерацией кода и показания загрузки процессора? а как интерпретировать то что у меня все наоборот? это означает как минимум что все оказывается более разнообразно чем то что мы видим. наверно ситуация все таки рулится - нужно найти руль, и не ехать по дефолтной траектории. в любом случае спасибо - косяки нужно знать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Terminator 0 24 мая, 2017 Опубликовано 24 мая, 2017 (изменено) · Жалоба Снова попробовал последний свежак и споткнулся об memset :) size_t init_memory_pool(size_t mem_pool_size, void *mem_pool) { /******************************************************************/ tlsf_t *tlsf; bhdr_t *b, *ib; ... /* Zeroing the memory pool */ memset(mem_pool, 0, sizeof(tlsf_t)); ругань: .../tlsf/tlsf.c:480:5: warning: 'memset' writing 3180 bytes into a region of size 4 overflows the destination [-Wstringop-overflow=] memset((char*)mem_pool, 0, sizeof(tlsf_t)); ^ /tmp/ccutHzBY.s: Assembler messages: /tmp/ccutHzBY.s:3170: Error: offset out of range lto-wrapper: fatal error: /opt/arm-kgp-eabi/bin/arm-kgp-eabi-g++ returned 1 exit status mem_pool "достаётся" здесь: unsigned long* p = &__heap_start__; *p = 0; unsigned long* e = &__heap_end__; unsigned long len = (char*) e - (char*) p; pool = p; init_memory_pool(len, pool); __heap_start__ и __heap_end__ из .ld Без lto собирается, но не влезает. P. S. на такой же memset вставленный перед вызовом init_memory_pool, не ругается. Изменено 24 мая, 2017 пользователем Terminator Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 1 24 мая, 2017 Опубликовано 24 мая, 2017 · Жалоба и споткнулся об memset :) Интересно, а смотрели, что там компилятор нагенерировал в memset? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 25 июня, 2017 Опубликовано 25 июня, 2017 · Жалоба свежак www.klen.org/Files/DevTools/x86_64-kgp-linux-gnu/arm-kgp-eabi_@_x86_64-kgp-linux-gnu_20170625_PATENS.7z Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 24 августа, 2017 Опубликовано 24 августа, 2017 (изменено) · Жалоба Коллеги, хотелось бы взглянуть на качество кода околопоследних версий или последней обсуждаемого компилятора для таргетов ARM v4/v5 (32bit), ARM v6M, ARM v7M. Может ли кто-то выложить хексы любых исходников (С,С++), размером 8..30 КБ бинарного кода (в переводе на кекс будет 20..100 КБ) для обозначенных таргетов. В архиве zip/rar. Изменено 24 августа, 2017 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 19 сентября, 2017 Опубликовано 19 сентября, 2017 · Жалоба могу дамп одного из проектов дать, там в перемешку строки исходников и асм. видно что из чего получается. видно хорошо вышло или не очень. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться