No passado, eu incorporei arquivos de recursos (imagens) em programas convertendo-os primeiro em .o
arquivos usando o vinculador GNU. Por exemplo:
ld -r -b binary -o file.o file.svg
A partir do FreeBSD 12, o linker padrão mudou de GNU para LLVM. Embora o vinculador pareça entender as opções de linha de comando, isso resulta em um erro. Por exemplo:
ld -r -b binary -o file.o file.svg
ld: error: target emulation unknown: -m or at least one .o file required
Também tentei usar as opções de linha de comando da página de manual ld.lld(1) :
ld --relocatable --format=binary -o file.o file.svg
ld: error: target emulation unknown: -m or at least one .o file required
Estou usando a ferramenta correta? Preciso especificar um valor para a -m
opção?
Parece que você precisa adicionar
-z noexecstack
(Isso foi adicionado para binários ELF também no LLD 7.0.0 ). O padrão é ter uma região de pilha executável que seja vulnerável à exploração via memória de pilha . Sua imagem binária não possui uma pilha executável e acredito que seja por isso que ela falha. O erro o deixa confuso, pois solicita que você diga qual emulação de destino usar para sua pilha (que você não possui).David Herrmann fez todo o trabalho duro e encontrou uma solução multiplataforma que abrange:
A invocação mágica é então:
E na maioria das vezes você quer que esse segmento binário seja somente leitura:
ATUALIZAR:
Não consegui testar pois meu sistema estava:
Eu criei uma VM com o FreeBSD 12.0 para testar isso e descobri isso:
O
-z noexecstack
foi adicionado apenas na versão 7.0.0 e não está listado na página de manual da versão 6.0.1. Mais irritantemente, especificar valores não suportados para-z
não acionar um erro!Eu não atualizei para o LLVM 7 para testar se isso funciona. @Richard Smith encontrou uma solução adequada especificando a emulação
-m
em outra resposta. Essa rota seria muito mais fácil se o LLD listasse emulações suportadas com-V
.Se você usar o
file
comando onfile.o
, verá que ele se identifica como SYSV ELF. Isso pode ser bom o suficiente para você. Mas se você quiser exatamente o mesmo que o sistema, use oelf_amd64_fbsd
que é um alias paraelf_x86_64_fbsd
. Irritantementeld -V
não produz emulações suportadas com LLD como o GNU ld faz.elf_amd64_fbsd
é um alias paraelf_x86_64_fbsd
(ver D7837 e D24356 ). Espero que o LLD adicione as emulações à-V
saída.Depois de examinar a fonte, a emulação de destino correta para minha plataforma é elf_amd64 . Portanto, a conversão de binário para arquivo de objeto funciona usando:
Será que realmente vale a pena? Isso não era portátil em primeiro lugar.
Você deve converter melhor seu .svg para um array de caracteres C; Exemplo:
Claro, você pode definir o nome do array para algo diferente / mais robusto (por exemplo
char $(subst /,_,$*)[] = ...
, em vez dechar $*[] = ...
com GNU make). Além disso, você pode construir um conversor ad-hocbin2c
escrito em C em vez daquele horrível combo od+sed.