Как узнать адрес секции, созданной через #pragma data_seg()

Тема в разделе "LANGS.C", создана пользователем 7mm, 31 май 2010.

  1. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Собственно вопрос: как это сделать в MSVC++? Есть вариант, запихнуть в начало секции переменную, адрес которой будет равен адресу секции. Но имхо как-то это не кошерно. Зачем же тратить для этого место :) Короче, есть ли какие-нить способы получить этот адрес в виде константы в процессе линковки?..
     
  2. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    вроде бы линкер предоставляет только __ImageBase

    вместо переменной в начале секции данных, можно использовать чтото в конце секции кода )
     
  3. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Понятно, также, через жопу ;)
     
  4. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Бало бы можно, CRT бы инициализировала статики по другому.
     
  5. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    А как она их?..
     
  6. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    /*
    * From the CRT sources and an article by Matt Pietrek, we get
    * the following information:
    *
    * The compiler emits a table of pointers to static constructors
    * to a special section ".CRT$XCU". The linker combines sections
    * with identical names, and as a special feature, it combines
    * sections with a '$' in their name, so they are ordered
    * asciibetically by the part after the '$'.
    *
    * So by defining a variable in a section called ".CRT$XCA" and
    * another in a section called ".CRT$XCZ", we get pointers to
    * the beginning and end of the ".CRT$XCU" section.
    */

    #pragma data_seg(".CRT$XCA")
    _PVFV __xc_a[] = { 0 };

    #pragma data_seg(".CRT$XCZ")
    _PVFV __xc_z[] = { 0 };
     
  7. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    JOE
    Угу, понял. Это я видел где-то уже. Думал, о другом речь. Спасибо ;)
     
  8. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    На самом деле, нет необходимости в переменной. Достаточно, чтобы был определён символ, принадлежащий секции и имеющий в качестве относительного адреса ноль. Но здесь есть определённые сложности с обработкой этого в разных режимах (т.е. всё равно получается некий хак). Чуть позже покажем пример.
     
  9. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Ага, символ. Это интересно, покажите пожалуйста :)
     
  10. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Sol_Ksacap
    По вашей наводке, накидал вот такой вариант: добавил к проекту asm-файл вот такого содержания:
    Код (Text):
    1. .686
    2. .model flat
    3.  
    4. PUBLIC C __InitSectionStart
    5. PUBLIC C __InitSectionEnd
    6.  
    7. INIT$A SEGMENT DWORD PUBLIC FLAT alias(".init$a")
    8.         __InitSectionStart EQU $
    9. INIT$A ENDS
    10.  
    11. INIT$Z SEGMENT DWORD PUBLIC FLAT alias(".init$z")
    12.         __InitSectionEnd EQU $
    13. INIT$Z ENDS
    14.  
    15. END
    После этого, в сишном коде:
    Код (Text):
    1. #pragma data_seg(".init$u")
    2. int token1 = 0xdeadbeef;
    3. int token2 = 0xdeadc0de;
    4. #pragma data_seg()
    MAP-файл:
    Код (Text):
    1.  Start         Length     Name                   Class
    2.  0003:00000000 00000000H .init$a                 DATA
    3.  0003:00000000 00000008H .init$u                 DATA
    4.  0003:00000008 00000000H .init$z                 DATA
    5.  
    6.   Address         Publics by Value              Rva+Base       Lib:Object
    7.  0003:00000000       ?token1@@3HA               10005000     dllmain.obj
    8.  0003:00000000       ___InitSectionStart        10005000     section.obj
    9.  0003:00000004       ?token2@@3HA               10005004     dllmain.obj
    10.  0003:00000008       ___InitSectionEnd          10005008     section.obj
    Соответственно, в map-файле и самом образе всё пучком: переменная есть, символы тоже определены :) Вроде бы, этот вариант устраивает. У вас что-то другое было, или так же?..
     
  11. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    7mm
    Да, у нас использовался тот же принцип. Хотелось сделать универсальный объектник – но пришлось отказаться от этого из-за возможности объединения секций. (Например, задан символ 'rdata_seg', определяющий начало '.rdata' – но, например, при отключённой инкрементальной линковке в начало .rdata мержится IAT (.idata$5), таким образом отменяя соответствие адреса 'rdata_seg' фактическому VA сегмента).