Собственно вопрос: как это сделать в MSVC++? Есть вариант, запихнуть в начало секции переменную, адрес которой будет равен адресу секции. Но имхо как-то это не кошерно. Зачем же тратить для этого место Короче, есть ли какие-нить способы получить этот адрес в виде константы в процессе линковки?..
вроде бы линкер предоставляет только __ImageBase вместо переменной в начале секции данных, можно использовать чтото в конце секции кода )
/* * 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 };
На самом деле, нет необходимости в переменной. Достаточно, чтобы был определён символ, принадлежащий секции и имеющий в качестве относительного адреса ноль. Но здесь есть определённые сложности с обработкой этого в разных режимах (т.е. всё равно получается некий хак). Чуть позже покажем пример.
Sol_Ksacap По вашей наводке, накидал вот такой вариант: добавил к проекту asm-файл вот такого содержания: Код (Text): .686 .model flat PUBLIC C __InitSectionStart PUBLIC C __InitSectionEnd INIT$A SEGMENT DWORD PUBLIC FLAT alias(".init$a") __InitSectionStart EQU $ INIT$A ENDS INIT$Z SEGMENT DWORD PUBLIC FLAT alias(".init$z") __InitSectionEnd EQU $ INIT$Z ENDS END После этого, в сишном коде: Код (Text): #pragma data_seg(".init$u") int token1 = 0xdeadbeef; int token2 = 0xdeadc0de; #pragma data_seg() MAP-файл: Код (Text): Start Length Name Class 0003:00000000 00000000H .init$a DATA 0003:00000000 00000008H .init$u DATA 0003:00000008 00000000H .init$z DATA Address Publics by Value Rva+Base Lib:Object 0003:00000000 ?token1@@3HA 10005000 dllmain.obj 0003:00000000 ___InitSectionStart 10005000 section.obj 0003:00000004 ?token2@@3HA 10005004 dllmain.obj 0003:00000008 ___InitSectionEnd 10005008 section.obj Соответственно, в map-файле и самом образе всё пучком: переменная есть, символы тоже определены Вроде бы, этот вариант устраивает. У вас что-то другое было, или так же?..
7mm Да, у нас использовался тот же принцип. Хотелось сделать универсальный объектник – но пришлось отказаться от этого из-за возможности объединения секций. (Например, задан символ 'rdata_seg', определяющий начало '.rdata' – но, например, при отключённой инкрементальной линковке в начало .rdata мержится IAT (.idata$5), таким образом отменяя соответствие адреса 'rdata_seg' фактическому VA сегмента).