64-разрядная Linux по умолчанию использует небольшую модель памяти, которая ставит все код и статические данные ниже предела адреса 2 ГБ. Это позволяет использовать 32-битные абсолютные адреса. Более старые версии gcc используют 32-разрядные абсолютные адреса для статических массивов, чтобы сохранить дополнительную инструкцию для вычисления относительных адресов. Однако это больше не работает. Если я попытаюсь создать 32-разрядный абсолютный адрес в сборке, я получаю ошибку компоновщика: "Перемещение R_X86_64_32S против`.data 'не может использоваться при создании общего объекта, перекомпиляция с -fPIC". Это сообщение об ошибке вводит в заблуждение, конечно, потому что я не делаю общий объект, а -fpIC не помогает. То, что я выяснил до сих пор, следующее: gcc версия 4.8.5 использует 32-битные абсолютные адреса для статических массивов, gcc-версия 6.3.0 этого не делает. версия 5, вероятно, тоже. Компилятор в binutils 2.24 допускает 32-битные абсолютные адреса, verson 2.28 - нет.
Следствием этого изменения является то, что старые библиотеки должны быть перекомпилированы, а устаревший код сборки нарушен.
Теперь я хочу спросить: когда это было сделано? Это где-то задокументировано? И есть ли опция компоновщика, которая позволяет принимать 32-битные абсолютные адреса?