O que é uma interface binária de Aplicação (ABI)?

Nunca percebi claramente o que é um ABI. Por favor, não me apontes um artigo da Wikipédia. Se eu entendesse, eu não estaria aqui postando um post tão longo.

Esta é a minha mentalidade sobre diferentes interfaces. Um comando de TV é uma interface entre o Usuário e a TV. É uma entidade existente, mas inútil (não fornece nenhuma funcionalidade) por si só. Toda a funcionalidade para cada um desses botões no remoto é implementada na televisão definir.

Interface: é uma camada de "entidade existente" entre a functionality e consumer disso funcionalidade. Uma interface por si só não faz nada. É que ... invoca a funcionalidade deitada tras.

Agora dependendo de quem o usuário está lá são diferentes tipos de interfaces.

Os comandos da interface da linha de comandos (CLI) são as entidades existentes, o consumidor é o utilizador e a funcionalidade fica para trás.

functionality: o meu software funcionalidade que resolve alguns objectivo a que estamos a descrever interface.

existing entities: comandos

consumer: utilizador

interface gráfica de utilizador(GUI) janela, botões, etc. são os existentes entidades, e mais uma vez o consumidor é o utilizador e a funcionalidade está atrás.

functionality: o meu software funcionalidade que resolve alguns objectivo a que estamos a descrever interface.

existing entities: janela, botões etc..

consumer: utilizador

interface de programação de aplicações(API) ou a ser mais correcto, interfaces (em a programação baseada em interfaces) é a entidades existentes, o consumidor aqui é outro programa não um usuário, e novamente a funcionalidade está atrás desta camada.

functionality: o meu software funcionalidade que resolve alguns objectivo a que estamos a descrever interface.

existing entities: funções, Interfaces (matriz de funções).

consumer: Outro programa / aplicação.

interface binária de Aplicação (ABI) aqui é onde o meu problema começa.

functionality: ???

existing entities: ???

consumer: ???

  • escrevi software em diferentes línguas e forneci diferentes tipos de interfaces (CLI, GUI e API), mas não tenho a certeza se alguma vez, provi algum ABI.

Wikipédia diz::

ABIs cobre pormenores como

  • Tipo de dados, tamanho e alinhamento;
  • a Convenção chamadora, que controla o modo como os argumentos das funções são valores passados e devolvidos recuperados;
  • os números de chamadas do sistema e como uma aplicação deve fazer chamadas do sistema para o sistema operativo;

outros pormenores da normalização da ABIs, tais como

  • the C++ name mangling,
  • excepção propagação, e
  • A convocar uma convenção entre compiladores na mesma plataforma, mas ... não necessita de plataformas cruzadas compatibilidade.
  • Quem precisa destes detalhes? Por favor, não digas "so". Conheço programação de montagem. Eu sei como a ligação e carregamento funciona. Sei exactamente o que acontece lá dentro.

  • porque é que a codificação de nomes C++ entrou? Pensei que estávamos a falar a nível binário. Porque é que as línguas entram?

De qualquer forma, eu ... downloaded the [PDF] System V Application Binary Interface Edition 4.1 (1997-03-18) para ver o que contém exactamente. A maior parte não fazia sentido.

  • Por que contém dois capítulos (4 e 5) para descrever o formato de arquivo ELF? Na verdade, estes são os dois únicos capítulos significativos dessa Especificação. O resto dos capítulos são "processador específico". De qualquer forma, eu pensei que era um tópico completamente diferente. Por favor não digas que as especificações do formato de ficheiro ELF são a ABI. Não se qualifica para ser uma interface de acordo com a definição.

  • Eu sei, uma vez que estamos a falar a um nível tão baixo, deve ser muito específico. Mas eu não tenho certeza de como é" instruction set architecture (ISA) " específico?

  • Onde posso encontrar o ABI do Microsoft Windows?

Então, estas são as principais perguntas que me estão a incomodar.

Author: Peter Mortensen, 2010-01-31

14 answers

Uma maneira fácil de entender " ABI "é compará-lo com"API".

Você já está familiarizado com o conceito de uma API. Se você quiser usar as características de, digamos, alguma biblioteca ou seu SO, você vai usar uma API. A API consiste em tipos de dados / estruturas, constantes, funções, etc que você pode usar em seu código para acessar a funcionalidade desse componente externo.

Um ABI é muito semelhante. Pense nisso como a versão compilada de uma API (ou como uma API na nível de linguagem de máquina). Quando você escreve código fonte, você acessar a biblioteca através de uma API. Uma vez que o código é compilado, sua aplicação acessa os dados binários na biblioteca através da ABI. A ABI define as estruturas e métodos que sua aplicação compilada irá usar para acessar a biblioteca externa (assim como a API fez), apenas em um nível inferior.

Os ABIs são importantes quando se trata de aplicações que utilizam bibliotecas externas. Se um programa é construído para usar uma biblioteca em particular e essa Biblioteca é atualizada mais tarde, você não quer ter que re-compilar essa aplicação (e do ponto de vista do usuário final, você pode não ter a fonte). Se a biblioteca atualizada usar o mesmo ABI, então seu programa não precisará mudar. A interface para a biblioteca (que é tudo o que o seu programa realmente se preocupa) é a mesma, mesmo que o funcionamento interno pode ter mudado. Duas versões de uma biblioteca que tem o mesmo ABI são por vezes chamadas de "binárias-Compatíveis", uma vez que eles têm o mesmo ABI. interface de baixo nível (você deve ser capaz de substituir a versão antiga com a nova e não ter quaisquer problemas principais).

Por vezes, as mudanças na ABI são inevitáveis. Quando isso acontece, quaisquer programas que usem essa biblioteca não funcionarão a menos que eles sejam re-compilados para usar a nova versão da biblioteca. Se a ABI muda, mas a API não, então as versões antiga e nova da biblioteca são algumas vezes chamadas de "fonte compatível". Isto implica que enquanto um programa compilado para uma versão de biblioteca não vai trabalhar com o outro, código fonte escrito para um vai trabalhar para o outro se re-compilado. Por esta razão, os escritores da biblioteca tendem a tentar manter seu ABI estável (para minimizar a perturbação). Manter um ABI estável significa não mudar as interfaces de função (tipo de retorno e número, tipos e ordem de argumentos), definições de tipos de dados ou estruturas de dados, constantes definidas, etc. Novas funções e tipos de dados podem ser adicionados, mas os existentes devem permanecer os mesmos. Se você expandir, digamos, um Dados de 16 bits estrutura do campo em um campo de 32 bits e, em seguida, já compilado código que utiliza a estrutura de dados não será o acesso a esse campo (ou qualquer seguintes) corretamente. Acessar os membros da estrutura de dados é convertido em endereços de memória e compensações durante a compilação e se a estrutura de dados muda, então essas compensações não vai apontar para o que o código está esperando que eles apontem e os resultados são imprevisíveis no melhor dos casos. Um ABI não é necessariamente algo que você vai explicitamente forneça a menos que você esteja esperando que as pessoas façam interface com o seu código usando o conjunto. Também não é específico de linguagem, Uma vez que (por exemplo) uma aplicação C e uma aplicação Pascal irão usar o mesmo ABI depois de serem compilados.

Edit: em relação à sua pergunta sobre os capítulos relativos ao formato de ficheiro ELF nos documentos do SysV ABI: a razão pela qual esta informação está incluída é porque o formato ELF define a interface entre o sistema operativo e a aplicação. Quando você diz o SO para executar um programa, ele espera que o programa seja formatado de uma certa forma e (por exemplo) espera que a primeira seção do binário seja um cabeçalho ELF contendo certas informações em compensações de memória específicas. É assim que a aplicação comunica informações importantes sobre si mesma ao sistema operacional. Se você construir um programa em um formato binário não-ELF( como um. out ou PE), então um sistema operacional que espera aplicações ELF formatadas não será capaz de interpretar o arquivo binário ou executar aplicacao. Esta é uma grande razão pela qual o Windows apps não pode ser executado diretamente em uma máquina Linux (ou vice-versa) sem ser re-compilado ou executado dentro de algum tipo de camada de emulação que pode traduzir de um formato binário para outro.

IIRC, O Windows usa actualmente o formatoportátil (ou, PE). Há links na seção" links externos " dessa página da Wikipédia com mais informações sobre o formato PE.

Também, em relação à sua nota sobre C++ name mangling: a ABI pode definir uma forma "padronizada" para um compilador C++ fazer mangling de nomes com o propósito de compatibilidade. Isto é, se eu criar uma biblioteca e desenvolver um programa que usa a biblioteca, você deve ser capaz de utilizar um compilador diferente do que eu fiz e não têm de se preocupar com os binários resultantes ser incompatíveis devido a diferentes desconfiguração do nome esquemas. Isto só é realmente de uso se você estiver definindo um novo formato de arquivo binário ou escrevendo um compilador ou linker.

 362
Author: bta, 2018-07-05 14:42:26

Se você conhece a montagem e como as coisas funcionam no nível OS, você está em conformidade com um certo ABI. A ABI governa coisas como como como os parâmetros são passados, onde os valores de retorno são colocados. Para muitas plataformas há apenas um ABI para escolher, e nesses casos o ABI é apenas "como as coisas funcionam".

No entanto, a ABI também governa coisas como a forma como as classes/objetos são definidos em C++. Isto é necessário se você quiser ser capaz de passar referências de objetos através dos limites do módulo ou se você quer misturar código compilado com compiladores diferentes.

Também, se você tem um SO de 64 bits que pode executar binários de 32 bits, você terá ABIs diferentes para código de 32 - e 64-bits.

Em geral, qualquer código que se ligue ao mesmo executável deve estar em conformidade com o mesmo ABI. Se você quiser se comunicar entre o código usando ABIs diferentes, você deve usar alguma forma de protocolos de RPC ou serialização.

Acho que estás a esforçar-te demais para encaixar diferentes tipos de interfaces num conjunto fixo de características. Por exemplo, uma interface não precisa necessariamente ser dividida em consumidores e produtores. Uma interface é apenas uma Convenção pela qual duas entidades interagem.

ABIs pode ser (parcialmente) ISA-agnóstico. Alguns aspectos (como chamar convenções) dependem da ISA, enquanto outros aspectos (como layout de Classe C++) não.

Um ABI bem definido é muito importante para as pessoas que escrevem Compiladores. Sem uma ABI bem definida, seria impossível gerar código interoperável.

Editar: algumas notas para clarificar:

  • "binário" em ABI não exclui o uso de cadeias de caracteres ou texto. Se você quiser ligar um DLL a exportar uma classe C++, em algum lugar nele os métodos e assinaturas de tipo devem ser codificados. É aí que entra o mutilador de nomes C++.
  • A razão pela qual você nunca forneceu um ABI é que a grande maioria dos programadores nunca o fará. Os ABIs são fornecidos pelas mesmas pessoas que concebem a plataforma (ou seja, o sistema operativo), e muito poucos programadores terão o privilégio de projetar um ABI amplamente utilizado.
 97
Author: JesperE, 2010-02-27 15:11:18

Uma interface binária de Aplicação (ABI) é semelhante a uma API, mas a função não é acessível ao chamador ao nível do código fonte. Apenas uma representação binária é acessível / disponível.

O ABIs pode ser definido ao nível da arquitectura do processador ou ao nível do sistema operacional. Os ABIs são padrões a serem seguidos pela fase gerador de código do compilador. O padrão é fixado pelo SO ou pelo processador.

Funcionalidade: definir o mecanismo / padrão para fazer a função chama independente da linguagem de implementação ou um compilador/linker/toolchain específico. Forneça o mecanismo que permite JNI, ou uma interface Python-C, etc.

Entidades existentes: funções sob a forma de código de máquina.

Consumidor: outra função (incluindo uma Numa outra língua, compilada por outro compilador, ou ligada por outro linker).

 16
Author: alvin, 2017-09-15 23:31:42

Você realmente não precisa de um ABI em tudo se--

    O seu programa não tem funções e ...
  • o seu programa é um único executável que está a correr sozinho (ou seja, um sistema incorporado) onde é literalmente a única coisa a correr e não precisa de falar com mais nada.

Um resumo simplificado:

API: "Aqui estão todas as funções que você pode chamar."

ABI: "Isto é Como chamar uma função."

A ABI é um conjunto de regras que Compiladores e linkers aderem, a fim de compilar o seu programa para que funcione adequadamente. Os ABIs abrangem vários tópicos:

    A maior e mais importante parte de um ABI é, sem dúvida, a chamada padrão de procedimento, por vezes conhecida como "Convenção de chamadas". Chamar convenções padronizar como "funções" são traduzidas para código de montagem. [8]ABIs também dita como o os nomes das funções expostas nas bibliotecas devem ser representados para que outros códigos possam chamar essas bibliotecas e saibam que argumentos devem ser passados. Isto chama-se"mutilação de nomes".
  • O ABIs também determina que tipo de dados podem ser utilizados, como devem ser alinhados e outros detalhes de baixo nível.

Olhando mais profundamente para a Convenção de chamadas, que eu considero ser o núcleo de um ABI:

A própria máquina não tem nenhum conceito de "funções". Quando escreves um function in a high-level language like c, the compiler generates a line of assembly code like _MyFunction1:. Este é um label , que eventualmente será resolvido em um endereço pelo montador. Este rótulo marca o" início "da sua" função " no código de montagem. Em código de alto nível, quando você "chama" essa função, o que você está realmente fazendo é fazer com que a CPU para saltar para o endereço dessa etiqueta e continuar executando lá.

Em preparação para o salto, o compilador deve fazer um monte de coisas importantes. A Convenção de chamadas é como uma lista de verificação que o compilador segue para fazer todas estas coisas:

  • Primeiro, o compilador introduz um pouco de código de montagem para salvar o endereço atual, de modo que quando a sua "função" é feita, a CPU pode saltar de volta para o lugar certo e continuar a executar.
  • A seguir, o compilador gera código de montagem para passar os argumentos.
      Algumas convenções apelativas ditam que os argumentos devem ser colocados na pilha. ( numa ordem específica claro.
    • outras convenções determinam que os argumentos devem ser colocados em registos específicos (dependendo dos seus tipos de dados, é claro).
    • ainda há outras convenções que ditam a utilização de uma combinação específica de pilha e registos.
    É claro que, se havia algo importante nesses registos antes, esses valores são agora substituídos e perdidos para sempre, por isso algumas convenções chamadoras podem ditar que o compilador deve salvar alguns desses registros antes de colocar os argumentos neles.
  • Agora o compilador insere uma instrução de salto dizendo à CPU para ir para a etiqueta que fez anteriormente ({[[0]}). Neste ponto, você pode considerar a CPU como " em " sua "função".
  • no final da função, o compilador coloca algum código de montagem que fará com que a CPU escreva o valor de retorno no lugar correto. A Convenção de chamamento vai ditar se o valor de retorno deve ser colocado em um registro particular (dependendo de seu tipo), ou na pilha.
  • Está na hora da limpeza. A Convenção de chamamento vai ditar onde o compilador coloca o código de montagem de limpeza.
      Algumas convenções dizem que quem liga deve limpar a pilha. Isto significa que depois que a "função" é feita e a CPU salta de volta para onde estava antes, o código seguinte a ser executado deve ser algum código de limpeza muito específico. Outras convenções dizem que algumas partes em particular do código de limpeza deve estar no final da" função " antes de {[5] } o salto de volta.
Existem muitas convenções ABIs / calling diferentes. Alguns dos principais são:
  • para a CPU x86 ou x86-64 (ambiente de 32 bits):
    • decl
    • STDCALL
    • FASTCALL
    • VECTORCALL
    • este plano
  • para a CPU x86-64 (64 bits) ambiente):
    • SYSTEMV
    • MSNATIVO
    • VECTORCALL
  • para a CPU do braço (32 bits)
    • AAPCS
  • para a CPU ARM (64 bits)
    • AAPCS64

Aqui está uma grande página que realmente mostra as diferenças na montagem gerada ao compilar para ABIs diferentes.

Outra coisa a mencionar é que um ABI não é apenas relevante {[[4]} dentro do módulo executável do seu programa. É ... Também usado pelo linker para garantir que o seu programa chama a biblioteca correctamente. Você tem várias bibliotecas compartilhadas em execução em seu computador, e desde que o seu compilador sabe o que ABI cada um usa, ele pode chamar funções a partir deles corretamente sem explodir a pilha.

O seu compilador compreender como chamar funções de Biblioteca éextremamente importante . Em uma plataforma hospedada (ou seja, uma onde um sistema operacional carrega programas), seu programa nem sequer pode piscar sem a fazer uma chamada.

 14
Author: Lakey, 2016-12-30 20:40:46

Funcionalidade: um conjunto de contratos que afectam o compilador, os escritores de montagem, o linker e o sistema operativo. Os contratos especificam como as funções são estabelecidas, onde os parâmetros são passados, como os parâmetros são passados, como a função retorna funciona. Estes são geralmente específicos de uma tupla (arquitetura de processador, sistema operacional).

Entidades existentes: disposição dos parâmetros, semântica das funções, atribuição dos registos. Por exemplo, as arquiteturas ARM tem inúmeros ABIs (APCS), EABI, GNU-EABI, não importa um monte de casos históricos) - usar o a mixed ABI resultará em seu código simplesmente não funcionar ao chamar através de fronteiras.

O compilador, os escritores de montagem, o sistema operativo, a arquitectura específica da CPU. Quem precisa destes detalhes? O compilador, escritores de montagem, linkers que fazem geração de código (ou requisitos de alinhamento), Sistema Operacional (manipulação de interrupção, interface syscall). Se você fez programação de montagem, você estava em conformidade com an ABI!

O codificador de nomes C++ é um caso especial - é um problema centrado no linker e dinâmico-se o codificador de nomes não for padronizado, então a ligação dinâmica não funcionará. A partir de Agora, o C++ ABI é chamado apenas isso, o C++ ABI. Não é uma questão de nível linker, mas sim uma questão de geração de código. Uma vez que tenha uma binária C++, não é possível torná-la compatível com outra ABI C++ (codificação de nomes, tratamento de exceções) sem recompilar a partir do Código.

O ELF é um formato de ficheiro para o uso de um carregador e linker dinâmico. ELF é um formato de contêiner para código binário e dados, e como tal especifica o ABI de um pedaço de código. Eu não consideraria o ELF um ABI no sentido estrito, já que os executáveis de PE não são um ABI.

Todos os ABIs são específicos do conjunto de instruções. Um ARM ABI não fará sentido em um processador MSP430 ou x86_64.

O Windows tem vários ABIs - por exemplo, fastcall e stdcall são dois ABIs de uso comum. O syscall ABI está diferente outra vez.

 9
Author: Yann Ramin, 2010-03-23 06:26:25
Deixe-me ao menos responder a uma parte da sua pergunta. Com um exemplo de como o Linux ABI afeta o systemcalls, e por que isso é útil.

A systemcall é uma forma de um programa userspace pedir algo ao kernelspace. Ele funciona colocando o código numérico para a chamada e o argumento em um determinado registro e desencadeando uma interrupção. Do que uma mudança ocorre no kernelspace e o kernel olha para cima o código numérico e o argumento, lida com a solicitação, coloca o resultado de volta num registo e acciona um interruptor de volta para o espaço do utilizador. Isto é necessário, por exemplo, quando a aplicação quer alocar memória ou abrir um arquivo (syscalls "brk" e "open").

Agora os syscalls têm nomes curtos "brk", etc. e opcodes correspondentes, estes são definidos em um arquivo de cabeçalho específico do sistema. Desde que estes opcodes permaneçam os mesmos, você pode executar os mesmos programas de userland compilados com diferentes kernels atualizados sem ter que recompilar. Então você tem uma interface usada por binarys pré-compilados, daí ABI.

 6
Author: snies, 2010-01-31 09:56:07

A melhor maneira de diferenciar a ABI da API é saber porquê e para que é utilizada:

Para x86-64 existe geralmente um ABI (e para x86 32 bits existe outro set):

Http://www.x86-64.org/documentation/abi.pdf

Https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/LowLevelABI/140-x86-64_Function_Calling_Conventions/x86_64.html

Http://people.freebsd.org/~Brien / amd64-elf-abi.pdf

Linux + FreeBSD + MacOSX seguem - no com algumas ligeiras variações. E o Windows x64 tem o seu próprio ABI:

Http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/

Conhecendo a ABI e assumindo que outro compilador também a segue, então os binários teoricamente sabem como chamar uns aos outros (API de bibliotecas em particular) e passar parâmetros sobre a pilha ou por registradores, etc. Ou que registos serão alterados ao chamar as funções etc. Essencialmente, estes conhecimentos ajudarão o software a integrar-se entre si. Conhecer a ordem do registradores / layout de pilha eu posso facilmente montar diferentes softwares escritos em conjuntos juntos, sem muito problema.

Mas a API é diferente:

É um nome de funções de alto nível, com argumento definido, tal que se diferentes peças de software constroem usando esta API, podem ser capazes de chamar uns aos outros. Mas um requisito adicional da mesma ABI deve ser cumprido.

Por exemplo, O Windows costumava ser a API POSIX conforme:

Https://en.wikipedia.org/wiki/Windows_Services_for_UNIX

Https://en.wikipedia.org/wiki/POSIX

E o Linux também é compatível com o POSIX. Mas os binários não podem ser movidos e executados imediatamente. Mas como eles usaram os mesmos nomes na API compatível com POSIX, você pode pegar o mesmo software em C, recompilá-lo nos diferentes SO, e imediatamente colocá-lo em execução.

API são destinados a facilitar integração de software-fase de pré-compilação. Então, após a compilação o software pode parecer totalmente diferente - se o ABI são diferentes.

ABI são destinados a definir a integração exata do software no nível binário / conjunto.

 4
Author: Peter Teoh, 2016-01-22 05:02:37

Para chamar código em bibliotecas compartilhadas, ou código de chamada entre unidades de compilação, o arquivo objeto precisa conter etiquetas para as chamadas. O C++ mangles the names of method labels in order to force data hiding and allow for overloaded methods. É por isso que você não pode misturar arquivos de diferentes compiladores C++ a menos que eles explicitamente suportam o mesmo ABI.

 3
Author: Justin Smith, 2010-02-01 03:48:23

Resumo

Existem várias interpretações e opiniões fortes da camada exata que definem um ABI (interface binária de Aplicação).

Na minha opinião, uma ABI é uma convenção subjectiva do que é considerado uma dada/plataforma para uma API específica. A ABI é o" resto "de convenções que" não mudarão " para uma API específica ou que serão abordadas pelo ambiente de execução: executores, ferramentas, linkers, Compiladores, jvm e OS.

[13] Interface : ABI, API

Se quiser usar uma biblioteca como a joda-time, deve declarar uma dependência de {[[0]}. A biblioteca segue as melhores práticas e utiliza versionamento semântico . Isto define a compatibilidade da API em três níveis:

    Patch-não precisa de alterar o seu código. A biblioteca só arranja alguns insectos. Menor-Você não precisa mudar seu código desde as adições
  1. Major-a interface (API) foi alterada e você talvez precises de mudar o teu código.

Para que você possa usar um novo lançamento importante da mesma biblioteca, muitas outras convenções ainda devem ser respeitadas:

  • a linguagem binária usada para as bibliotecas (nos casos Java, a versão alvo JVM que define o bytecode Java)
  • A chamar as convenções.
  • convenções JVM
  • ligação das convenções
  • Convenções de tempo de execução Todos estes são definidos e geridos pelas ferramentas que usar.

Exemplos

Estudo de caso Java

Por exemplo, Java padronizou todas estas convenções, não em uma ferramenta, mas em uma especificação JVM formal. A especificação permitiu que outros fornecedores fornecessem um conjunto diferente de ferramentas que podem produzir bibliotecas compatíveis.

Java fornece dois outros estudos de caso interessantes para ABI: versões Scala e dalvik máquina virtual.

A máquina virtual Dalvik partiu a ABI.

O VM Dalvik necessita de um tipo diferente de bytecode do que o bytecode Java. As bibliotecas Dalvik são obtidas convertendo o bytecode Java (com a mesma API) para Dalvik. Desta forma, você pode obter duas versões da mesma API: definida pelo joda-time-1.7.2.jar original. Podíamos chamar-me de joda-time-1.7.2.jar e joda-time-1.7.2-dalvik.jar. Eles usam um ABI diferente para o padrão Java VMs de stack-oriented: Oracle's one, IBM one, open Java ou qualquer outro; e o segundo ABI é o em torno de Dalvik.

Scala as sucessivas versões são incompatível

Scala não tem compatibilidade binária entre versões Scala menores: 2.X. Por esta razão, a mesma API " io.reativex "% % "rxscala" % "0.26.5" tem três versões (no futuro mais): para Scala 2.10, 2.11 e 2.12. O que mudou? Não sei por enquanto, mas os binários não são compatíveis. Provavelmente as versões mais recentes adicionam coisas que tornam as bibliotecas inutilizáveis nas máquinas virtuais antigas, provavelmente coisas relacionadas com linking / naming / parameter convencao.

As versões sucessivas de Java são incompatíveis

Java também tem problemas com os principais lançamentos da JVM: 4,5,6,7,8,9. Eles oferecem apenas compatibilidade reversa. O Jvm9 sabe como executar código compilado / alvo (opção javac -target) para todas as outras versões, enquanto o JVM 4 não sabe como executar código alvo para o JVM 5. Tudo isto enquanto tens uma biblioteca joda. Esta incompatibilidade voa abaixo do radar graças a diferentes soluções:

    Semântica versioning: quando as bibliotecas têm como alvo JVM superior, elas geralmente mudam a versão principal.
  1. usa o JVM 4 como ABI, e estás segura.
  2. o Java 9 adiciona uma especificação sobre como pode incluir o bytecode para o JVM específico na mesma biblioteca.
Porque comecei com a definição da API?

API e ABI são apenas convenções sobre como se define compatibilidade. As camadas inferiores são genéricas em relação a uma infinidade de semântica de alto nível. É por isso que é fácil faz algumas convenções. O primeiro tipo de convenções é sobre alinhamento de memória, codificação de bytes, chamadas de Convenções, grandes e pequenas codificações endianas, etc. Em cima deles você obtém as convenções executáveis como as outras descritas, vinculando convenções, código de byte intermediário Como o usado por Java ou LLVM IR usado pelo GCC. Em terceiro lugar, você obtém convenções sobre como encontrar bibliotecas, como carregá-las (veja java classloaders). À medida que você vai mais e mais alto em conceitos, você tem novas convenções que considera como um dado adquirido. Por isso não chegaram à versão semântica. Estão implícitas ou colapsadas na versão maior. Poderíamos alterar a versionação semântica com <major>-<minor>-<patch>-<platform/ABI>. Isto é o que está realmente acontecendo já: plataforma já é um rpm, dll, jar (JVM bytecode), war (JVM+servidor web), apk, 2.11 (versão Scala específica) e assim por diante. Quando você diz APK você já fala sobre uma parte específica ABI de sua API.

A API pode ser portada para diferente ABI

O Nível Superior de uma abstração (as fontes escritas contra a API mais alta podem ser recompiladas/portadas para qualquer outra abstração de nível inferior.

Digamos que tenho algumas fontes para o rxscala. Se as ferramentas Scala forem mudadas posso recompilá-las a isso. Se o JVM mudar eu poderia ter conversões automáticas da máquina velha para a nova sem incomodar com os conceitos de alto nível. Enquanto o porting pode ser difícil vai ajudar qualquer outro cliente. Se um novo o sistema operacional é criado usando um código de montagem totalmente diferente um tradutor pode ser criado.

APIs portadas em todas as línguas

Existem APIs que são portadas em várias línguas comofluxos reactivos . Em geral, definem mapeamentos para linguagens/plataformas específicas. Eu argumentaria que a API é a especificação mestre formalmente definida na linguagem humana ou mesmo uma linguagem de programação específica. Todos os outros "mappings" são ABI em um sentido, mais API do que o habitual. O mesmo está acontecendo com as demais interfaces.

 2
Author: raisercostin, 2017-09-15 23:42:45
A ABI tem de ser consistente entre o chamador e o callee para ter a certeza de que a chamada é bem sucedida. Utilização da pilha, utilização do registo, Estojo de fim de rotina. Todas estas são as partes mais importantes da ABI.
 1
Author: Ignacio Vazquez-Abrams, 2010-01-31 09:42:07
Em resumo e em Filosofia, apenas as coisas de um tipo {3]} podem dar-se bem, e a ABI pode ser vista como o tipo do qual as coisas de software funcionam em conjunto.
 1
Author: smwikipedia, 2010-02-26 15:50:29
Também estava a tentar entender que a resposta da ABI e do JesperE era muito útil.

De uma perspectiva muito simples, podemos tentar compreender a ABI considerando a compatibilidade binária.

O wiki do KDE define uma biblioteca como binária compatível " Se um programa ligado dinamicamente a uma versão anterior da biblioteca continuar a correr com versões mais recentes da biblioteca sem a necessidade de recompilar."Para mais informações sobre a ligação dinâmica, ver ligação estática vs dinâmica ligação

Agora, vamos tentar olhar apenas para os aspectos mais básicos necessários para que uma biblioteca seja compatibilidade binária (assumindo que não há alterações de código fonte na Biblioteca):

  1. a mesma / backward compatible instruction set architecture (processor instructions, register file structure, stack organization, memory access types, along with sizes, layout, and alignment of basic data types the processor can directly access)
  2. As mesmas convenções de apelação.
  3. o mesmo Convenção de mangling de nomes (isto pode ser necessário se um programa Fortran precisar chamar alguma função de biblioteca C++).
Claro, há muitos outros detalhes, mas isto é principalmente o que a ABI também cobre. Mais especificamente para responder à sua pergunta, podemos deduzir:

Funcionalidade ABI: compatibilidade binária

Entidades existentes: programa existente / bibliotecas / OS

Consumidor: bibliotecas, OS
Espero que isto ajuda!
 1
Author: blue_whale, 2017-06-21 17:08:05

Interface binária de Aplicação (ABI)

Funcionalidade:

    Tradução do modelo do programador para os dados de domínio do sistema subjacente Tipo, tamanho, alinhamento, a Convenção de chamamento, que controla como os argumentos das funções são passados e os valores de retorno recuperados; números de chamadas do sistema e como um aplicativo deve fazer chamadas do sistema para o sistema operativo; o nome dos compiladores de línguas de alto nível esquema de mutilação, propagação de exceções e chamamento convencao entre compiladores na mesma plataforma, mas não exigem compatibilidade entre plataformas...

Entidades Existentes:

    Blocos lógicos que participam directamente na execução do programa: ALU, registos de finalidade geral, registos para mapeamento de memória/ I/O de E / S, etc...

Consumidores:

    Processadores de linguagem linker, montador...
[[1]Estas são necessárias por quem tem que garantir que construir correntes de ferramentas funcionam como um todo. Se você escrever um módulo em linguagem assembly, outro em Python, e em vez de seu próprio carregador de boot quer usar um sistema operacional, então seus módulos de "aplicação" estão trabalhando através dos limites "binários" e exigem o Acordo de tal "interface".

Codificação de nomes em C++ porque os ficheiros de objectos de diferentes linguagens de alto nível podem ser necessários para serem ligados na sua aplicação. Considere o uso de biblioteca padrão GCC fazendo chamadas de Sistema Para Windows construídos com C++Visual.

Elfo é uma possível expectativa do linker a partir de um arquivo objeto para interpretação, embora a JVM possa ter alguma outra ideia.

Para uma aplicação do Windows RT Store, tente procurar o ARM ABI se quiser mesmo fazer com que a cadeia de ferramentas do build funcione em conjunto.

 1
Author: Chawathe Vipul, 2017-09-15 23:34:19

O termo ABI é usado para se referir a dois conceitos distintos mas relacionados.

Ao falar de compiladores, refere-se às regras usadas para traduzir de construções de nível fonte para construções Binárias. De que tamanho são os tipos de dados? como funciona a pilha? como passo parâmetros para funções? que registos devem ser salvos pelo chamador contra o callee?

Quando se fala de bibliotecas, refere-se à interface binária apresentada por uma biblioteca compilada. Esta interface é a resultado de uma série de fatores, incluindo o código fonte da biblioteca, as regras usadas pelo compilador e, em alguns casos, as definições pegou de outras bibliotecas.

As mudanças numa biblioteca podem quebrar a ABI sem quebrar a API. Considere, por exemplo, uma biblioteca com uma interface como.
void initfoo(FOO * foo)
int usefoo(FOO * foo, int bar)
void cleanupfoo(FOO * foo)

E o programador de aplicações escreve código como

int dostuffwithfoo(int bar) {
  FOO foo;
  initfoo(&foo);
  int result = usefoo(&foo,bar)
  cleanupfoo(&foo);
  return result;
}

O programador da aplicação não se importa com o tamanho ou layout do FOO, mas o binário da aplicação termina com um tamanho duro de foo. Se o programador da biblioteca adicionar um campo extra para o foo e alguém usar o binário da nova biblioteca com o binário da aplicação antiga, então a biblioteca pode fazer fora dos limites acessos de memória.

OTOH se o autor da biblioteca tivesse desenhado a sua API como.

FOO * newfoo(void)
int usefoo(FOO * foo, int bar)
void deletefoo((FOO * foo, int bar))

E o programador de aplicações escreve código como

int dostuffwithfoo(int bar) {
  FOO * foo;
  foo = newfoo();
  int result = usefoo(&foo,bar)
  deletefoo(&foo);
  return result;
}

Então o binário da aplicação não precisa saber nada sobre a estrutura do FOO, que pode estar tudo escondido dentro da biblioteca. Preco você paga por isso, no entanto, é que heap operações estão envolvidas.

 1
Author: plugwash, 2018-06-25 02:35:05