Interface: UserModManager Arquivos: usermodmanager.h Última atualização: 25/06/2005 Autor: Luiz Henrique Shigunov |
Descrição Estruturas Configuração |
Funções para o sistema | |
0x00 - Exit - Finaliza a execução de um módulo 0x01 - Register - Registra uma biblioteca |
0x02 - Unregister - Retira do registro uma biblioteca |
Funções para o usuário | |
0x04 - UCatchException - Registra o tratador de exceções 0x05 - UExit - Finaliza a execução de um módulo do usuário 0x06 - UGetFunction - Obtém o ponteiro para uma função de uma biblioteca registrada ou do sistema 0x07 - UGetLibFunction - Obtém uma função de uma biblioteca carregada 0x08 - UGetShutdownFunctionI - Obtém o ponteiro para a função de término de uma biblioteca |
0x09 - UGetStackSize - Obtém o tamanho da pilha 0x0a - UGetStartFunction - Obtém o ponteiro para a função de iniciação de uma biblioteca 0x0b - UGetStartFunctionI - Obtém o ponteiro para a função de iniciação de uma biblioteca 0x0c - ULoad - Carrega uma biblioteca 0x0d - UUnload - Descarrega uma biblioteca |
Esta página descreve a interface UserModManager que trata dos módulos executáveis e bibliotecas.
Existem dois tipos de módulos do usuário: o módulo executável (pode ser executado como um programa) e o módulo biblioteca (apenas fornece funções para os módulos executáveis ou bibliotecas).
O registro de um módulo biblioteca significa disponibilizar as funções das interfaces implementadas pelo módulo biblioteca para os demais módulos do usuário.
Um módulo biblioteca deve implementar uma ou mais interfaces, cada implementação com uma ou mais funções. Cada implementação implementa apenas uma interface.
Ao contrário das interfaces e implementações de interfaces, as funções têm número de identificação e não nome.
Um módulo biblioteca é formado por código das funções, dados somente leitura, dados iniciados e dados não iniciados (são iniciados com zero).
Um módulo executável é formado por código, dados somente leitura, dados iniciados e dados não iniciados (são iniciados com zero).
Toda biblioteca usada por um módulo executável, seja estatica ou dinamicamente, deve ser iniciada antes de ser usada e terminada antes do programa terminar.
As funções UGetStartFunctionI e UGetShutdownFunctionI foram feitas para iniciar/terminar as bibliotecas usadas estaticamente.
Já a função UGetStartFunction foi feita para iniciar as bibliotecas usadas dinamicamente.
As bibliotecas usadas dinamicamente são terminadas usando a função UGetShutdownFunctionI para evitar que ela seja terminada quando ainda está sendo usada.
É possível que a função de iniciação de uma biblioteca seja chamada várias vezes. A biblioteca tem que controlar isso.
Cada função que pode ser usada por módulos do usuários tem um número que indica quantas palavras (4 bytes) ela deve receber dos módulos do usuários. Essas palavras são copiadas da pilha do usuário para a pilha do sistema quando a função é chamada. Este é o mesmo esquema de passagem de parâmetros usado no FreeBSD e no Microsoft Windows NT.
typedef union { InterManager_Event iEvent; UserModManager_Events uEvent; } UserModManager_Event;
Esta union é usada para evitar os avisos de type-punned no gcc. Para as funções da interface Intermanager usamos o iEvent já para as funções desta interface usamos o uEvent.
typedef struct { unsigned int type; union { UserModManager_ChildEvent child; UserModManager_TermEvent term; }; } UserModManager_Events;
type é o tipo do evento e pode ser:
typedef struct { unsigned int code; int pid; int exitCode unsigned int res[4]; } UserModManager_ChildEvent;
code indica o motivo do evento:
pid é o identificador da tarefa filha, exitCode é o codigo de retorno da tarefa filha se code for UserModManager_CHILD_EXITED ou tem estes valores se code for UserModManager_CHILD_DUMPED:
typedef struct { unsigned int res[7]; } UserModManager_TermEvent;
Esta interface define os seguintes grupos e chaves disponíveis através da interface CfgManager:
/system/UserModManager/modules | ||
Os módulos bibliotecas registrados permanentemente ficam neste grupo. Cada módulo tem um grupo dentro desse grupo que tem as seguintes chaves:
Alguns exemplos:
Grupo /system/UserModManager/modules/memmanager, chaves:
|
Estas funções são de uso exclusivo dos módulos do sistema.
int UserModManager_Exit(TaskManager_Task *task, int exitCode);
Esta função finaliza a tarefa task.
Se task for NULL, finaliza a tarefa chamadora.
task tem que estar marcada indestrutível.
Lembre-se que uma tarefa executando código do sistema já está marcada indestrutível, ou seja, se task for NULL você não precisa chamar a função UndestroyableThread e se task não for NULL ela já está marcada indestrutível ou você não poderia usar task.
exitCode é o código de retorno.
int UserModManager_Register(const char *pathname, int prop);
Esta função registra o módulo biblioteca pathname.
prop deve ser 0 ou:
int UserModManager_Unregister(const char *pathname, int prop);
Esta função retira do registro o módulo biblioteca pathname.
prop deve ser 0 ou:
Só pode ser retirada uma biblioteca que não esteja em uso.
Estas funções foram projetadas para os módulos do usuário.
int UserModManager_UCatchException(void *function);
Do usuário
Esta função registra a função function para tratar as exceções que ocorrerem na tarefa.
Quando uma exceção ocorrer o controle é retornado para function, ou seja, o EIP de retorno passa a ser function.
Ao retornar para function a pilha vai conter: dados específicos de cada exceção, se existirem, endereço onde a exceção ocorreu e código da exceção, ou seja, ESP aponta para o código da exceção.
As exceções suportadas são:
Código | Descrição |
---|---|
0x00 | Ocorreu uma divisão por zero. |
0x01 | A instrução INTO (overflow) foi executada. |
0x02 | A instrução BOUND detectou uma tentativa de acesso fora dos limites de um vetor. |
0x03 | Instrução inválida. |
0x04 | Tentativa de acesso a dados não alinhados. |
0x05 | Violação de acesso à memória.
Esta exceção coloca os seguinte valores na pilha: endereço que causou a violação de acesso e um inteiro indicando se foi uma tentativa de escrita (diferente de 0) ou leitura (0). |
É da responsabilidade do programa arrumar a pilha para continuar a execução.
Se um tratador não estiver definido o programa é terminado.
Para remover o tratador é só chamar a função com um NULL.
void UserModManager_UExit(int exitCode);
Do usuário
Esta função termina o módulo executável e define o código de retorno para exitCode.
void *UserModManager_UGetFunction(const char *interface, const char *imp, unsigned int function, int type);
Do usuário
Esta função obtém o ponteiro para a função function da implementação imp da interface interface de um módulo biblioteca registrado ou do sistema.
type deve ser:
A função do módulo do sistema tem que ser uma função do usuário.
Utilize as macros IS_PTR_ERROR e PTR_TO_ERROR para saber se ocorreu erro e para obter o erro respectivamente.
void *UserModManager_UGetLibFunction(UserModManager_Library *lib, const char *interface, const char *imp, unsigned int function);
Do usuário
Esta função obtém o ponteiro para a função function da implementação imp da interface interface da biblioteca lib.
lib é o identificador da biblioteca carregada pela função Load.
Utilize as macros IS_PTR_ERROR e PTR_TO_ERROR para saber se ocorreu erro e para obter o erro respectivamente.
void *UserModManager_UGetShutdownFunctionI(unsigned int index);
Do usuário
Esta função obtém o ponteiro para a função de término da biblioteca.
index deve começar em zero e ser incrementado a cada chamada da função.
Se a biblioteca não tiver função de término, esta função retorna 0xffffffff.
Antes de um programa ser terminado a função de término de cada biblioteca usada estaticamente deve ser chamada. Por exemplo:
i = 0; while ((shutdown = UserModManager_UGetShutdownFunctionI(i++))) { if ((unsigned int)shutdown != 0xffffffff) shutdown(); }
O ponteiro para a função ou NULL em caso de erro.
unsigned int UserModManager_UGetStackSize(void);
Do usuário
Esta função obtém o tamanho da pilha em bytes que é alocada quando a primeira linha de execução da tarefa é criada.
O valor retornado é uma potência de 2.
void *UserModManager_UGetStartFunction(void *function);
Do usuário
Esta função obtém o ponteiro para a função de iniciação da biblioteca que implementa function.
Se a biblioteca não tiver função de iniciação, esta função retorna NULL.
Antes de uma biblioteca usada dinamicamente ser usada a função de iniciação deve ser chamada. Por exemplo:
start = UserModManager_UGetStartFunction(MyLibrary_Func1); if (start) start();
Esta função deve ser usada para iniciar módulos biblioteca que foram usados dinamicamente.
O ponteiro para a função ou NULL em caso de erro.
void *UserModManager_UGetStartFunctionI(unsigned int index);
Do usuário
Esta função obtém o ponteiro para a função de iniciação da biblioteca.
index deve começar em zero e ser incrementado a cada chamada da função.
Se a biblioteca não tiver função de iniciação, esta função retorna 0xffffffff.
Antes de uma biblioteca usada estaticamente ser usada a função de iniciação deve ser chamada. Por exemplo:
i = 0; while ((start = UserModManager_UGetStartFunctionI(i++))) { if ((unsigned int)start != 0xffffffff) start(); }
O ponteiro para a função ou NULL em caso de erro.
int UserModManager_ULoad(const char *pathname, UserModManager_Library **lib);
Do usuário
Esta função carrega a biblioteca pathname.
A iniciação da biblioteca, se for necessária, deve ser feita por que usa a biblioteca.
Em caso de sucesso, lib conterá o identificador da biblioteca carregada.
int UserModManager_UUnload(UserModManager_Library *lib);
Do usuário
Esta função descarrega a biblioteca lib.