1. C++ / Говнокод #21425

    −18

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    uint64_t ObjectLoadListener::getRelocationAddend(uint64_t LLVMRelocationType,
                                                     uint8_t *FixupAddress) {
      uint64_t Addend = 0;
      switch (LLVMRelocationType) {
      case IMAGE_REL_AMD64_ABSOLUTE:
        Addend = *(uint32_t *)FixupAddress;
        break;
      case IMAGE_REL_AMD64_ADDR64:
        Addend = *(uint64_t *)FixupAddress;
        break;
      case IMAGE_REL_AMD64_REL32:
        Addend = *(uint32_t *)FixupAddress;
        break;
      default:
        llvm_unreachable("Unknown reloc type.");
      }
      return Addend;
    }

    https://github.com/dotnet/llilc/blob/97cf48ea9a3cdf4a2582a95683a74b572f4cfe45/lib/Jit/LLILCJit.cpp#L770-L787

    Надеюсь, мне не нужно объяснять, в чем тут говно?

    Запостил: j123123, 12 Октября 2016

    Комментарии (142) RSS

    • Как так!? В универе за подобное в лабах - и то, ссаными тряпками били
      Ответить
    • >>Надеюсь, мне не нужно объяснять, в чем тут говно?

      нет, там сверху в углу написанно
      Ответить
    • Можно все-таки объяснить?
      Ответить
      • https://spin.atomicobject.com/2014/05/19/c-undefined-behaviors/
        2. Upcasting Pointers
        Ответить
        • А если всё-таки нужно вытащить длинное значение с нечётного адреса, то нужно копировать ручками по байтикам?
          Ответить
          • memcpy()
            Ответить
            • Самое главное — вовремя развести дебаты, что лучше использовать: memcpy() или memmove().
              Ответить
              • Если у тебя свежезапиленная временная переменная на стеке пересекается с куском памяти, на который указывает FixupAddress, боюсь, у тебя проблемы похуже выбора между memcpy/memmove...
                Ответить
                • Если я правильно понял Царя, то всё это не важно. Главное, чтобы код правильно отработал на тестовом примере.
                  Ответить
                  • показать все, что скрытоЭтот код работает потому что царь знает как это работает
                    Ответить
                  • - Почему у вас релиз не собирается?
                    - Релиз? Пацаны, я всю жизнь на дебаге собираю, УМСР.
                    - А Почему юнит тесты падают?
                    - Пацаны, это не я, я такого вообще не пишу
                    Ответить
                  • показать все, что скрытоничего не знаю, у меня дома всё работало (как вариант "у меня на компьютере")
                    Ответить
                    • Надо не в оборону уходить, а с выпадом.

                      У вас говно вместо конпелятора, а входные данные вообще какая-то питушня писала. Возьмите gcc последний, линукс 64 бит, и данные на входе чоткие должны быть, а не питушня.
                      Ответить
        • > C++
          > /c-undefined-behaviors/

          Ну ладно, я тебя понял.
          Ответить
          • А есть ли такое, чтоб некаяхуйня в Си была бы UB, а в плюсах бы это было нормальным (определенным) поведением?
            Ответить
            • main без return'а (можешь скомпилить с -std=c89 и полюбоваться UB'ом во всей красе).
              Ответить
              • Указатель на инструкцию отправится в кругосветку по оперативе?
                Ответить
            • показать все, что скрытоХотя нет, поясни еще. Что за fixupaddress? А может там на самом деле эти типы лежат?
              Ответить
              • Ну пойди и проанализируй код
                getRelocationAddend вызывается тут: https://github.com/dotnet/llilc/blob/97cf48ea9a3cdf4a2582a95683a74b572f4cfe45/lib/Jit/LLILCJit.cpp#L761

                FixupAddress получается так:
                uint8_t *FixupAddress = (uint8_t *)(SectionAddress + Offset);

                Если дальше ковырять это говно, можно найти

                uint64_t Offset = I->getOffset();

                и
                uint64_t SectionAddress = L.getSectionLoadAddress(*Section);

                надо еще вот этот класс проанализировать
                https://github.com/dotnet/llilc/blob/9d6a522deb6b0769e449f27a087a9d3a7ab2a255/lib/Reader/reader.cpp#L112

                uint32_t getOffset(void) const { return Offset; }

                Что-то мне лень анализировть все это говно, но достаточно очевидно, что этот Offset показывает смешения в байтах в MSIL (он же CIL) байткоде, этот байткод не имеет фиксированного размера инструкций, так что там вполне может быть какая-то параша с выравниванием, не кратным 4 или 8 байтам
                Ответить
    • показать все, что скрытоТам вместо uint8_t нужно использовать void?
      Ответить
      • Не спасёт, если указатель не выравнен соответственно.
        Ответить
        • Да даже если выровнен - рано или поздно на алиасинг напорешься. Тлен и безысходность.
          Ответить
          • показать все, что скрытоЧо за алиасинг?
            Ответить
            • > Чо за алиасинг?
              "Ну не могут же uint8_t и uint64_t лежать в одном и том же месте!" - подумал конпелятор и выкинул код нахуй.
              Ответить
              • показать все, что скрытоПример кода можно?
                Ответить
                • Можно:
                  void foo(uint32_t a)
                  {
                      uint8_t *p = (uint8_t*)&a;
                      printf("%02X %02X %02X %02X", p[0], p[1], p[2], p[3]);
                  }
                  Ответить
                  • показать все, что скрытоhttp://ideone.com/Z8ay2B
                    Что за хуйня? Мне показалось, или оно вывело байты в обратном порядке? Ты про это?
                    Ответить
                    • В обратном порядке - вполне ожидаемо, маленький индеец же.

                      З.Ы. Бля, ща попробую воспроизведение замутить. Что-то все примеры из инета перестали UB триггерить.

                      На пока почитай: http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
                      Ответить
                      • Ну чё-за хуита, gcc походу поумнел и на простых примерах алиасинг не получается словить...
                        Ответить
                        • гцц - умнее большенства человеков с 1987 года
                          Ответить
                      • показать все, что скрытоНу а как тогда реализовать свою функцию memcpy без нарушения strict aliasing? Как не крути ей придётся разъименовывать указатели.
                        Ответить
                        • Через char*. Он имеет право с чем угодно алиаситься.
                          Ответить
                          • показать все, что скрытотак вроде войда и не было у K&R, был только char*.

                            Логичнее было бы назвать бедолагу "byte*", но боюсь что это слово тогда не было де-факто
                            Ответить
                          • а void*?

                            п.с. в pcap указатель на контекст передается через u_char. Тлен и безысходность
                            Ответить
                    • На Интелах и прочих маленьких индейцах так и будет. На этих процессорах просто принято числа записывать в таком порядке.

                      Но я подозреваю, что речь не об этом.
                      Ответить
                      • показать все, что скрытоНихуя себе!!!
                        Всегда думал что старшее слово имеет меньший адрес.
                        Ответить
                        • https://en.wikipedia.org/wiki/Endianness

                          Есть ещё процессоры со смешанным порядком (PDP-11, в котором старшее двухбайтовое слово имеет меньший адрес, но внутри каждого двухбайтового слова старший октет имеет больший адрес). А на ARM можно вообще переключать порядок октетов на ходу.
                          Ответить
                          • показать все, что скрытоТо есть вообще нельзя никак полагаться на способ хранения различных типов? То есть хак
                            union { 
                               uint16_t a[2];
                               uint32_t b;
                            } x;
                            x.b =123;
                            swap(x.a[0], x.a[1]);
                            x.b

                            - это всё нерабочее?
                            Ответить
                            • Ну почему же. Данный код рабочий. Вот только в каком из элементов a[0], a[1] будет лежать старший байт числа 123 (который равен нулю), а в каком — младший (равный 0x7b), можно сказать, только зная процессор (а на ARM, PowerPC, Alpha, SPARC, MIPS ещё нужно знать текущий режим работы).
                              Ответить
                              • P.S. Мне сначала показалось, что там uint8_t и uint16_t. Поэтому мой текст нужно исправить: вместо «байт» следует читать «16-битное слово».
                                Ответить
                                • показать все, что скрытоНу на это можно полагаться или это UB и компилятор может выкинуть мой код нахуй?
                                  Ответить
                                  • показать все, что скрытоПредставление чисел - implementation defined. А твой хак с юнионом - ub.
                                    Ответить
                                    • показать все, что скрытоВо-во
                                      Я это и хотел соснуть
                                      Ответить
                                      • показать все, что скрытоНа всякий случай уточню. На способ представления чисел полагаться можно, ub не в этом.
                                        Ответить
                                        • показать все, что скрытоКак тогда обменять 2 половинки int32 без UB, полагаясь на их представление?
                                          Ответить
                                          • > Как тогда обменять 2 половинки int32 без UB
                                            Сдвигами же.

                                            З.Ы. А, ты не про uint32, а про int32 - никак, переполнение, все дела... Разве что кучу ифов нахерачить, чтобы переполнения не задевать.
                                            Ответить
                                            • показать все, что скрыто> сдвигами
                                              Где здесь используется представление чисел?
                                              (0b111 >> 1) == 0b11
                                              и мне похуй где располагается старшее слово, а где младшее
                                              Ответить
                                            • Товарищ, поясните, чем представления беззнакового инта отличается от знакового? Я по наивности думал, что только интерпретация разная
                                              Ответить
                                              • > чем представления беззнакового инта отличается от знакового
                                                Тем, что переполнение в знаковый разряд - UB.

                                                А общее у них только представление положительных чисел до 0 .. 2^(n-1) - 1. Отрицательные - implementation defined.
                                                Ответить
                                                • Нихуя не понима...

                                                  Допустим есть

                                                  1010111010 - некий 10битный чисел с первой половиной 10101 и второй 11010

                                                  нужно получить
                                                  1101010101

                                                  Причем тут переполнение? Причем тут знаковый разряд?
                                                  Ответить
                                                  • Когда будешь сдвигать 11010 влево на 5 - наступишь в UB (старшая единичка заедет в знаковый разряд).
                                                    Ответить
                                                    • а если с max_uint32 через & перекрутить? Тоже UB?
                                                      Ответить
                                                      • Каст беззнакового не из диапазона 0 .. 2^(n-1) в знаковое, емнип, тоже UB. Ну т.е. тебе придётся знаковый бит аккуратно if'ами сформировать или математикой какой-нить.
                                                        Ответить
                                                        • а наху почему так?
                                                          Ответить
                                                          • > почему так
                                                            Свободу процессорам и компиляторам!

                                                            Например можно реализовать проверку на переполнение, как в шарпике, и убивать прогу нахуй... Или сделать saturated числа. Стандарт не запрещает.
                                                            Ответить
                                                            • А Еще существуют места, где пишут код под конкретную версию конкретного процессора, который компилится исключительно в полнолуние?
                                                              Ответить
                                                              • > конкретную версию конкретного процессора
                                                                Эмбедщина.
                                                                Ответить
                                                                • Дяденька, я ведь не настоящий программист...

                                                                  Что такое Эмбедщина?
                                                                  Ответить
                                                                  • > Эмбедщина
                                                                    Программирование для встраиваемых устройств (аля микроконтроллеры).
                                                                    Ответить
                                                                    • Видимо круг сего крайне узок
                                                                      Ответить
                                                                      • Это очень специфичная область. И программисты там бывают двух типов: "Программы - фигня, главное - железку собрать." и борманды.
                                                                        Ответить
                                                                        • Сишники, паскалисты. борманды, пхпешники...
                                                                          Ответить
                                                          • З.Ы. Ну и конпелятор может делать всякие оптимизации, учитывая что знаковое число не переполняется. К примеру, если он знает, что A положительно, то 2 * A тоже положительно...

                                                            Где-то здесь был пример адовых оптимизаций циклов, которые прокатывали только с int, но не с size_t.
                                                            Ответить
                                          • показать все, что скрытоКастишь в char* и меняешь местами байты. Как отметил j123123, для копирования байтов удобно использовать memcpy.
                                            Ответить
                            • показать все, что скрытоЭто UB.
                              Ответить
                        • показать все, что скрытоНихуя себе!!!

                          Ты не знал про байт ордер?

                          А чего ты еще не знал?
                          Ответить
              • void* и char* алиясятся со всем. Воид по дизайну, чар из-за обратной совместимости.

                Но signed/unsigned char* не альясятся со всем.
                Ответить
    • показать все, что скрытоЗачем тогда компилятор разрешает так кастить, если это заведомо UB?
      Ответить
    • в кои-то веки годный тред
      Ответить
    • Надо было писать на расте, там такое говно хотя бы компилятор не позволит сделать без обмазывания unsafe.
      Ответить
      • показать все, что скрытоФанбой в этом итт треде. Интересно, когда фанбои начнут резать ягнят в жертву компилятору.
        Ответить
      • Там по слухам и односвязный список нельзя написать без обмазывания unsafe. Это как секьюрность уровня: "давайте _все_ файлы сможет читать и писать только рут".
        Ответить
        • показать все, что скрытоТрахни меня в жопчик плз :3
          Ответить
        • Вот тут пишут, как сделать двусвязный список без unsafe https://www.reddit.com/r/rust/comments/2u53le/this_is_a_doubly_linked_list_in_safe_rus t/

          Фактически, поверх вектора сделан свой аллокатор с индексами вместо сырых указателей. Несложно догадаться, что с таким аллокатором можно написать любые виды багов: и мертвые "ссылки", и порча "кучи", и вообще любая хуйня. Еще оверхед на проверку индекса при доступе к элементам вектора. Зато безопасно, че.
          Ответить
        • > односвязный список нельзя написать без обмазывания unsafe
          Ну да, если пилить односвязные списки на каждый чих, как в сишечке, то всё будет обмазано unsafe'ами... Но ведь даже в крестах так не делают, а пилят контейнер и юзают его :)

          Профит подхода с unsafe в том, что опасные куски легко загрепать, перечитать и обмазать на 146% тестами. А остальной код чё-попало с памятью творить не сможет.
          Ответить
          • Здорово, что они обеспокоились безопасностью за счёт типизации. Это всегда благородно. Но, как пишет Пирс в первой главе тапла, любая система типизации всегда отбрасывает и корректные программы. Простые мономорфные типы, например, лишат программы тьюринговой полноты. Нафиг нужна такая статическая типизация? (На самом деле нужна)
            В расте статические проверки тоже слишком строгие, чтобы верифицировать интересные программы.
            Ответить
    • https://github.com/dotnet/llilc/blob/97cf48ea9a3cdf4a2582a95683a74b572f4cfe45/lib/Jit/LLILCJit.cpp#L624
      uint32_t LastDebugOffset = (uint32_t)-1;
      им бы не помешало стандарт почитать. Делать такую фигню совершенно необязательно.
      Ответить
    • показать все, что скрыто
       /     \             \            /    \       
      |       |             \          |      |      
      |       `.             |         |       :     
      `        |             |        \|       |     
       \       | /       /  \\\   --__ \\       :    
        \      \/   _--~~          ~--__| \     |    
         \      \_-~                    ~-_\    |    
          \_     \        _.--------.______\|   |    
            \     \______// _ ___ _ (_(__>  \   |    
             \   .  C ___)  ______ (_(____>  |  /    
             /\ |   C ____)/      \ (_____>  |_/     
            / /\|   C_____)       |  (___>   /  \    
           |   (   _C_____)\______/  // _/ /     \   
           |    \  |__   \\_________// (__/       |  
          | \    \____)   `----   --'             |  
          |  \_          ___\       /_          _/ | 
         |              /    |     |  \            | 
         |             |    /       \  \           | 
         |          / /    |         |  \           |
         |         / /      \__/\___/    |          |
        |           /        |    |       |         |
        |          |         |    |       |         | 
      				   |    |
        
      Ответить
    • показать все, что скрыто
      
      /     \             \            /    \        
      |       |             \          |      |      
      |       `.             |         |       :     
      `        |             |        \|       |     
       \       | /       /  \\\   --__ \\       :    
        \      \/   _--~~          ~--__| \     |    
         \      \_-~                    ~-_\    |    
          \_     \        _.--------.______\|   |    
            \     \______// _ ___ _ (_(__>  \   |    
             \   .  C ___)  ______ (_(____>  |  /    
             /\ |   C ____)/      \ (_____>  |_/     
            / /\|   C_____)       |  (___>   /  \    
           |   (   _C_____)\______/  // _/ /     \   
           |    \  |__   \\_________// (__/       |  
          | \    \____)   `----   --'             |  
          |  \_          ___\       /_          _/ | 
         |              /    |     |  \            | 
         |             |    /       \  \           | 
         |          / /    |         |  \           |
         |         / /      \__/\___/    |          |
        |           /        |    |       |         |
        |          |         |    |       |         |
      					   |    |				   
      

      Ответить
    • показать все, что скрыто
      
      /     \             \            /    \        
      |       |             \          |      |      
      |       `.             |         |       :     
      `        |             |        \|       |     
       \       | /       /  \\\   --__ \\       :    
        \      \/   _--~~          ~--__| \     |    
         \      \_-~                    ~-_\    |    
          \_     \        _.--------.______\|   |    
            \     \______// _ ___ _ (_(__>  \   |    
             \   .  C ___)  ______ (_(____>  |  /    
             /\ |   C ____)/      \ (_____>  |_/     
            / /\|   C_____)       |  (___>   /  \    
           |   (   _C_____)\______/  // _/ /     \   
           |    \  |__   \\_________// (__/       |  
          | \    \____)   `----   --'             |  
          |  \_          ___\       /_          _/ | 
         |              /    |     |  \            | 
         |             |    /       \  \           | 
         |          / /    |         |  \           |
         |         / /      \__/\___/    |          |
        |           /        |    |       |         |
        |          |         |    |       |         |
      					   |    |                  
      
      Ответить
    • показать все, что скрыто
      
      /     \             \            /    \        
      |       |             \          |      |      
      |       `.             |         |       :     
      `        |             |        \|       |     
       \       | /       /  \\\   --__ \\       :    
        \      \/   _--~~          ~--__| \     |    
         \      \_-~                    ~-_\    |    
          \_     \        _.--------.______\|   |    
            \     \______// _ ___ _ (_(__>  \   |    
             \   .  C ___)  ______ (_(____>  |  /    
             /\ |   C ____)/      \ (_____>  |_/     
            / /\|   C_____)       |  (___>   /  \    
           |   (   _C_____)\______/  // _/ /     \   
           |    \  |__   \\_________// (__/       |  
          | \    \____)   `----   --'             |  
          |  \_          ___\       /_          _/ | 
         |              /    |     |  \            | 
         |             |    /       \  \           | 
         |          / /    |         |  \           |
         |         / /      \__/\___/    |          |
        |           /        |    |       |         |
        |          |         |    |       |         |
      
      Ответить
    • показать все, что скрыто
      
      
      /     \             \            /    \        
      |       |             \          |      |      
      |       `.             |         |       :     
      `        |             |        \|       |     
       \       | /       /  \\\   --__ \\       :    
        \      \/   _--~~          ~--__| \     |    
         \      \_-~                    ~-_\    |    
          \_     \        _.--------.______\|   |    
            \     \______// _ ___ _ (_(__>  \   |    
             \   .  C ___)  ______ (_(____>  |  /    
             /\ |   C ____)/      \ (_____>  |_/     
            / /\|   C_____)       |  (___>   /  \    
           |   (   _C_____)\______/  // _/ /     \   
           |    \  |__   \\_________// (__/       |  
          | \    \____)   `----   --'             |  
          |  \_          ___\       /_          _/ | 
         |              /    |     |  \            | 
         |             |    /       \  \           | 
         |          / /    |         |  \           |
         |         / /      \__/\___/    |          |
        |           /        |    |       |         |
        |          |         |    |       |         |
      
      Ответить
    • показать все, что скрыто
      
      
      /     \             \            /    \        
      |       |             \          |      |      
      |       `.             |         |       :     
      `        |             |        \|       |     
       \       | /       /  \\\   --__ \\       :    
        \      \/   _--~~          ~--__| \     |    
         \      \_-~                    ~-_\    |    
          \_     \        _.--------.______\|   |    
            \     \______// _ ___ _ (_(__>  \   |    
             \   .  C ___)  ______ (_(____>  |  /    
             /\ |   C ____)/      \ (_____>  |_/     
            / /\|   C_____)       |  (___>   /  \    
           |   (   _C_____)\______/  // _/ /     \   
           |    \  |__   \\_________// (__/       |  
          | \    \____)   `----   --'             |  
          |  \_          ___\       /_          _/ | 
         |              /    |     |  \            | 
         |             |    /       \  \           | 
         |          / /    |         |  \           |
         |         / /      \__/\___/    |          |
        |           /        |    |       |         |
        |          |         |    |       |         |
      
      Ответить
    • показать все, что скрытоШандарахни меня в жопочник )
      Ответить

    Добавить комментарий