Encontrando deslocamentos de símbolos locais em bibliotecas compartilhadas programaticamente no OS X

Eu preciso encontrar o deslocamento de um símbolo local em uma biblioteca compartilhada no OS X. Símbolo local como no símbolo não exportado. Assim sendodyld("symbol_name") não funciona.

Eu posso no entanto usarnm para encontrar esses offsets, por exemplo

$ nm /System/Library/PrivateFrameworks/DesktopServicesPriv.framework/DesktopServicesPriv  | grep -e ChildSetLabel -e NodeVolumeEject
000000000006cccd T _NodeVolumeEject
000000000009dbd7 t __ChildSetLabel

Lá vemos o exportado (T) símboloNodeVolumeEject qual é o offset0x6cccd Eu posso facilmente revelar usandodyld("NodeVolumeEject"). dyld() revelará o endereço no espaço de endereço atual, mas estou satisfeito com o deslocamento na biblioteca compartilhada ou com o endereço absoluto no espaço de endereço. Além disso, há o local (t) símbolo_ChildSetLabel qual é compensado (0x9dbd7) Não posso revelar usandodyld().

Eu gostaria de poder fazer essa resolução programaticamente (semgobjdump, nm, otool, ou qualquer outro programa externo). Existe uma maneira "fácil" de conseguir isso? O código fonte das ferramentas mencionadas acima contém o código necessário, mas me pergunto se não há algo mais direto.

Domínio: A solução tem apenas que funcionar no OS X 10.8 ou melhor para binários x86_64 do MachO.

Esclarecimento: Eu ficaria feliz em descobrir o deslocamento absoluto no deslocamento atual (que devido a ASLR) não é estático, obviamente. Mas também fico feliz em descobrir o deslocamento em relação ao início dessa biblioteca, que permanece estática (até a recompilação). A parte de "endereço na biblioteca" para "endereço no espaço de endereço" é bastante fácil:

off_t sym_offset_child_set_label = ANSWER_TO_THIS_QUESTION("_ChildSetLabel");
Dl_info info;
void *abs_volume_eject = dlsym(RTLD_DEFAULT, "NodeVolumeEject");
void *abs_child_set_label = NULL;
if (dladdr(abs_volume_eject, &info)) {
    abs_child_set_label = (void *)((char *)info.dli_fbase + sym_offset_child_set_label);

    /* abs_child_set_label now points to the function in question */
}

Isto é, desde que_ChildSetLabel eNodeVolumeEject estão na mesma biblioteca compartilhada o suficiente. Portanto, o ASLR não é um problema aqui.

questionAnswers(1)

yourAnswerToTheQuestion