Как мне обратиться к глобальной переменной в динамически связанной библиотеке?

Средой является Solaris на 32-битной SPARC, но я думаю, что это более общая проблема с динамическим связыванием и /или позиционно-независимым кодом.

У меня есть программа сборки, которую я компилирую как независимый от позиции код и динамически связываю его с программой на Си. Он работает нормально, за исключением того, что я не могу сослаться на любую память, зарезервированную программой сборки из программы сборки. Прыжки внутри программы сборки работают нормально.

Я просто хочу читать и записывать в память в программе сборки, но каждый раз, когда я пытаюсь это сделать, я получаю ошибку сегментации.

Я написал эту тестовую программу для устранения этой проблемы

  .section ".data"
  .global foo
foo: .word 1
  .section ".text"
  .global testprog
testprog:
  save %sp, -(92+4), %sp
  sethi %hi(foo), %o0 ! set foo, %o0
  or %o0, %lo(foo), %o0 
  call print_int
  nop
  ret
  restore

Я скомпилирую это с помощью

  

как -K PIC -b

и добавьте получившийся .so в C

dlhandle = dlopen(obj_file, RTLD_NOW)
dl_testprog = dlsym(dlhandle, "testprog")

когда я звоню dl_testprog(), выводится «4». Он также печатает «4», если я пытаюсь напечатать адрес testprog или print_int. Переход на метку и все остальное работает просто отлично. Глядя на разборку, foo заменяется на 0x0, как и должно быть.

Должен ли я проходить через _GLOBAL_OFFSET_TABLE_ или что-то еще, чтобы иметь возможность писать в свою память в программе сборки? Если да, то как мне это сделать? Все, что я пробовал, привело к segfault, и я не смог найти очень хорошее руководство, как это сделать (что заставляет меня поверить, что вы не должны это делать. Разве это не проблема с линкерами?) .

4 голоса | спросил Venti 2 Maypm09 2009, 16:57:09

2 ответа


0

Решил это, посмотрев код, который выводит компилятор C для PIC, что я и должен был сделать с самого начала вместо чтения руководств и случайных веб-страниц.

Возможно, это было очевидно, но на самом деле реальный адрес объекта в PIC (по крайней мере, в 32b SPARC) - это (_GLOBAL_OFFSET_TABLE_ + PC + object). И условием является вычисление адреса GOT для% l7 в начале функции. Подробности: здесь , за исключением того, как фактически рассчитать% l7.

addpc:
  add %o7, %l7, %l7 ! %o7 == addr of call == PC
  retl
   nop
testprog:
  sethi %hi(_GLOBAL_OFFSET_TABLE_-8), %l7 ! -8 = distance from call addpc
  add %l7, %lo(_GLOBAL_OFFSET_TABLE_-4), %l7 
  call addpc ! add PC to %l7
   nop
ответил Venti 3 Mayam09 2009, 06:22:15
0

Да, я считаю, что вы должны пройти через GOT, чтобы обратиться к личным данным. См. Раздел 9.2 здесь . Хотя NASM является ассемблером x86, общие принципы должны быть такими же и в SPARC /Solaris.

Кроме того, AT & T ассемблеры обычно используют синтаксис '@got' для указания перемещения по отношению к. ПОЛУЧИЛ. Точные подробности будут описаны в вашем руководстве на ассемблере, то есть детали синтаксиса NASM не будут работать с ассемблером Solaris.

ответил zvrba 2 Maypm09 2009, 17:18:31

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132